Whamcloud - gitweb
LU-11673 tests: replace obsolete '-o' to '||'
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 # -*- tab-width: 8; indent-tabs-mode: t; -*-
3 #
4 # Run select tests by setting ONLY, or as arguments to the script.
5 # Skip specific tests by setting EXCEPT.
6 #
7 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
8 set -e
9
10 ONLY=${ONLY:-"$*"}
11 # bug number for skipped test: LU-9693 LU-6493 LU-9693
12 ALWAYS_EXCEPT="$SANITY_EXCEPT  42a     42b     42c"
13 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
14
15 # skipped tests: LU-8411 LU-9096 LU-9054 ..
16 ALWAYS_EXCEPT="  407     253     312     $ALWAYS_EXCEPT"
17
18 if $SHARED_KEY; then
19 # bug number for skipped tests: LU-9795 (all below)
20         ALWAYS_EXCEPT="$ALWAYS_EXCEPT   17n     60a     133g    300f"
21 fi
22
23 # Check Grants after these tests
24 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
25
26 # skip the grant tests for ARM until they are fixed
27 if [[ $(uname -m) = aarch64 ]]; then
28         # bug number:    LU-11596 (all below)
29         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
30         # bug number:    LU-11671 LU-11594 LU-11667 LU-11729
31         ALWAYS_EXCEPT+=" 45       103a      317      810"
32 fi
33
34 SRCDIR=$(cd $(dirname $0); echo $PWD)
35 export PATH=$PATH:/sbin
36
37 TMP=${TMP:-/tmp}
38 OSC=${OSC:-"osc"}
39
40 CC=${CC:-cc}
41 CHECKSTAT=${CHECKSTAT:-"checkstat -v"}
42 CREATETEST=${CREATETEST:-createtest}
43 LFS=${LFS:-lfs}
44 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
45 LCTL=${LCTL:-lctl}
46 OPENFILE=${OPENFILE:-openfile}
47 OPENUNLINK=${OPENUNLINK:-openunlink}
48 export MULTIOP=${MULTIOP:-multiop}
49 READS=${READS:-"reads"}
50 MUNLINK=${MUNLINK:-munlink}
51 SOCKETSERVER=${SOCKETSERVER:-socketserver}
52 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
53 MEMHOG=${MEMHOG:-memhog}
54 DIRECTIO=${DIRECTIO:-directio}
55 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
56 DEF_STRIPE_COUNT=-1
57 CHECK_GRANT=${CHECK_GRANT:-"yes"}
58 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
59 export PARALLEL=${PARALLEL:-"no"}
60
61 export NAME=${NAME:-local}
62
63 SAVE_PWD=$PWD
64
65 CLEANUP=${CLEANUP:-:}
66 SETUP=${SETUP:-:}
67 TRACE=${TRACE:-""}
68 LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
69 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
70 . $LUSTRE/tests/test-framework.sh
71 init_test_env $@
72 . ${CONFIG:=$LUSTRE/tests/cfg/${NAME}.sh}
73
74 init_logging
75
76 #                                  5          12          (min)"
77 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 300o"
78
79 if [ "$mds1_FSTYPE" = "zfs" ]; then
80         # bug number for skipped test: LU-1957
81         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  180"
82         #                                               13    (min)"
83         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
84 fi
85
86 # Get the SLES distro version
87 #
88 # Returns a version string that should only be used in comparing
89 # strings returned by version_code()
90 sles_version_code()
91 {
92         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
93
94         # All SuSE Linux versions have one decimal. version_code expects two
95         local sles_version=$version.0
96         version_code $sles_version
97 }
98
99 # Check if we are running on Ubuntu or SLES so we can make decisions on
100 # what tests to run
101 if [ -r /etc/SuSE-release ]; then
102         sles_version=$(sles_version_code)
103         [ $sles_version -lt $(version_code 11.4.0) ] &&
104                 # bug number for skipped test: LU-4341
105                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
106         [ $sles_version -lt $(version_code 12.0.0) ] &&
107                 # bug number for skipped test: LU-3703
108                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
109 elif [ -r /etc/os-release ]; then
110         if grep -qi ubuntu /etc/os-release; then
111                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
112                                                 -e 's/^VERSION=//p' \
113                                                 /etc/os-release |
114                                                 awk '{ print $1 }'))
115
116                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
117                         # bug number for skipped test:
118                         #                LU-10334 LU-10366
119                         ALWAYS_EXCEPT+=" 103a     410"
120                 fi
121         fi
122 fi
123
124 FAIL_ON_ERROR=false
125
126 cleanup() {
127         echo -n "cln.."
128         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
129         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
130 }
131 setup() {
132         echo -n "mnt.."
133         load_modules
134         setupall || exit 10
135         echo "done"
136 }
137
138 check_swap_layouts_support()
139 {
140         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
141                 skip "Does not support layout lock."
142 }
143
144 check_and_setup_lustre
145 DIR=${DIR:-$MOUNT}
146 assert_DIR
147
148 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
149
150 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
151 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
152 rm -rf $DIR/[Rdfs][0-9]*
153
154 # $RUNAS_ID may get set incorrectly somewhere else
155 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
156         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
157
158 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
159
160 build_test_filter
161
162 if [ "${ONLY}" = "MOUNT" ] ; then
163         echo "Lustre is up, please go on"
164         exit
165 fi
166
167 echo "preparing for tests involving mounts"
168 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
169 touch $EXT2_DEV
170 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
171 echo # add a newline after mke2fs.
172
173 umask 077
174
175 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
176 lctl set_param debug=-1 2> /dev/null || true
177 test_0a() {
178         touch $DIR/$tfile
179         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
180         rm $DIR/$tfile
181         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
182 }
183 run_test 0a "touch; rm ====================="
184
185 test_0b() {
186         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
187         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
188 }
189 run_test 0b "chmod 0755 $DIR ============================="
190
191 test_0c() {
192         $LCTL get_param mdc.*.import | grep "state: FULL" ||
193                 error "import not FULL"
194         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
195                 error "bad target"
196 }
197 run_test 0c "check import proc"
198
199 test_0d() { # LU-3397
200         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
201                 skip "proc exports not supported before 2.10.57"
202
203         local mgs_exp="mgs.MGS.exports"
204         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
205         local exp_client_nid
206         local exp_client_version
207         local exp_val
208         local imp_val
209         local temp_imp=$DIR/$tfile.import
210         local temp_exp=$DIR/$tfile.export
211
212         # save mgc import file to $temp_imp
213         $LCTL get_param mgc.*.import | tee $temp_imp
214         # Check if client uuid is found in MGS export
215         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
216                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
217                         $client_uuid ] &&
218                         break;
219         done
220         # save mgs export file to $temp_exp
221         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
222
223         # Compare the value of field "connect_flags"
224         imp_val=$(grep "connect_flags" $temp_imp)
225         exp_val=$(grep "connect_flags" $temp_exp)
226         [ "$exp_val" == "$imp_val" ] ||
227                 error "export flags '$exp_val' != import flags '$imp_val'"
228
229         # Compare the value of client version
230         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
231         exp_val=$(version_code $exp_client_version)
232         imp_val=$CLIENT_VERSION
233         [ "$exp_val" == "$imp_val" ] ||
234                 error "export client version '$exp_val' != '$imp_val'"
235 }
236 run_test 0d "check export proc ============================="
237
238 test_1() {
239         test_mkdir $DIR/$tdir
240         test_mkdir $DIR/$tdir/d2
241         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
242         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
243         rmdir $DIR/$tdir/d2
244         rmdir $DIR/$tdir
245         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
246 }
247 run_test 1 "mkdir; remkdir; rmdir"
248
249 test_2() {
250         test_mkdir $DIR/$tdir
251         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
252         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
253         rm -r $DIR/$tdir
254         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
255 }
256 run_test 2 "mkdir; touch; rmdir; check file"
257
258 test_3() {
259         test_mkdir $DIR/$tdir
260         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
261         touch $DIR/$tdir/$tfile
262         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
263         rm -r $DIR/$tdir
264         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
265 }
266 run_test 3 "mkdir; touch; rmdir; check dir"
267
268 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
269 test_4() {
270         test_mkdir -i 1 $DIR/$tdir
271
272         touch $DIR/$tdir/$tfile ||
273                 error "Create file under remote directory failed"
274
275         rmdir $DIR/$tdir &&
276                 error "Expect error removing in-use dir $DIR/$tdir"
277
278         test -d $DIR/$tdir || error "Remote directory disappeared"
279
280         rm -rf $DIR/$tdir || error "remove remote dir error"
281 }
282 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
283
284 test_5() {
285         test_mkdir $DIR/$tdir
286         test_mkdir $DIR/$tdir/d2
287         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
288         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
289         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
290 }
291 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
292
293 test_6a() {
294         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
295         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
296         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
297                 error "$tfile does not have perm 0666 or UID $UID"
298         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
299         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
300                 error "$tfile should be 0666 and owned by UID $UID"
301 }
302 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
303
304 test_6c() {
305         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
306
307         touch $DIR/$tfile
308         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
309         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
310                 error "$tfile should be owned by UID $RUNAS_ID"
311         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
312         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
313                 error "$tfile should be owned by UID $RUNAS_ID"
314 }
315 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
316
317 test_6e() {
318         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
319
320         touch $DIR/$tfile
321         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
322         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
323                 error "$tfile should be owned by GID $UID"
324         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
325         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
326                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
327 }
328 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
329
330 test_6g() {
331         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
332
333         test_mkdir $DIR/$tdir
334         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
335         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
336         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
337         test_mkdir $DIR/$tdir/d/subdir
338         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
339                 error "$tdir/d/subdir should be GID $RUNAS_GID"
340         if [[ $MDSCOUNT -gt 1 ]]; then
341                 # check remote dir sgid inherite
342                 $LFS mkdir -i 0 $DIR/$tdir.local ||
343                         error "mkdir $tdir.local failed"
344                 chmod g+s $DIR/$tdir.local ||
345                         error "chmod $tdir.local failed"
346                 chgrp $RUNAS_GID $DIR/$tdir.local ||
347                         error "chgrp $tdir.local failed"
348                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
349                         error "mkdir $tdir.remote failed"
350                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
351                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
352                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
353                         error "$tdir.remote should be mode 02755"
354         fi
355 }
356 run_test 6g "verify new dir in sgid dir inherits group"
357
358 test_6h() { # bug 7331
359         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
360
361         touch $DIR/$tfile || error "touch failed"
362         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
363         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
364                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
365         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
366                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
367 }
368 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
369
370 test_7a() {
371         test_mkdir $DIR/$tdir
372         $MCREATE $DIR/$tdir/$tfile
373         chmod 0666 $DIR/$tdir/$tfile
374         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
375                 error "$tdir/$tfile should be mode 0666"
376 }
377 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
378
379 test_7b() {
380         if [ ! -d $DIR/$tdir ]; then
381                 test_mkdir $DIR/$tdir
382         fi
383         $MCREATE $DIR/$tdir/$tfile
384         echo -n foo > $DIR/$tdir/$tfile
385         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
386         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
387 }
388 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
389
390 test_8() {
391         test_mkdir $DIR/$tdir
392         touch $DIR/$tdir/$tfile
393         chmod 0666 $DIR/$tdir/$tfile
394         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
395                 error "$tfile mode not 0666"
396 }
397 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
398
399 test_9() {
400         test_mkdir $DIR/$tdir
401         test_mkdir $DIR/$tdir/d2
402         test_mkdir $DIR/$tdir/d2/d3
403         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
404 }
405 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
406
407 test_10() {
408         test_mkdir $DIR/$tdir
409         test_mkdir $DIR/$tdir/d2
410         touch $DIR/$tdir/d2/$tfile
411         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
412                 error "$tdir/d2/$tfile not a file"
413 }
414 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
415
416 test_11() {
417         test_mkdir $DIR/$tdir
418         test_mkdir $DIR/$tdir/d2
419         chmod 0666 $DIR/$tdir/d2
420         chmod 0705 $DIR/$tdir/d2
421         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
422                 error "$tdir/d2 mode not 0705"
423 }
424 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
425
426 test_12() {
427         test_mkdir $DIR/$tdir
428         touch $DIR/$tdir/$tfile
429         chmod 0666 $DIR/$tdir/$tfile
430         chmod 0654 $DIR/$tdir/$tfile
431         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
432                 error "$tdir/d2 mode not 0654"
433 }
434 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
435
436 test_13() {
437         test_mkdir $DIR/$tdir
438         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
439         >  $DIR/$tdir/$tfile
440         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
441                 error "$tdir/$tfile size not 0 after truncate"
442 }
443 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
444
445 test_14() {
446         test_mkdir $DIR/$tdir
447         touch $DIR/$tdir/$tfile
448         rm $DIR/$tdir/$tfile
449         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
450 }
451 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
452
453 test_15() {
454         test_mkdir $DIR/$tdir
455         touch $DIR/$tdir/$tfile
456         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
457         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
458                 error "$tdir/${tfile_2} not a file after rename"
459         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
460 }
461 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
462
463 test_16() {
464         test_mkdir $DIR/$tdir
465         touch $DIR/$tdir/$tfile
466         rm -rf $DIR/$tdir/$tfile
467         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
468 }
469 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
470
471 test_17a() {
472         test_mkdir $DIR/$tdir
473         touch $DIR/$tdir/$tfile
474         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
475         ls -l $DIR/$tdir
476         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
477                 error "$tdir/l-exist not a symlink"
478         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
479                 error "$tdir/l-exist not referencing a file"
480         rm -f $DIR/$tdir/l-exist
481         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
482 }
483 run_test 17a "symlinks: create, remove (real)"
484
485 test_17b() {
486         test_mkdir $DIR/$tdir
487         ln -s no-such-file $DIR/$tdir/l-dangle
488         ls -l $DIR/$tdir
489         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
490                 error "$tdir/l-dangle not referencing no-such-file"
491         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
492                 error "$tdir/l-dangle not referencing non-existent file"
493         rm -f $DIR/$tdir/l-dangle
494         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
495 }
496 run_test 17b "symlinks: create, remove (dangling)"
497
498 test_17c() { # bug 3440 - don't save failed open RPC for replay
499         test_mkdir $DIR/$tdir
500         ln -s foo $DIR/$tdir/$tfile
501         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
502 }
503 run_test 17c "symlinks: open dangling (should return error)"
504
505 test_17d() {
506         test_mkdir $DIR/$tdir
507         ln -s foo $DIR/$tdir/$tfile
508         touch $DIR/$tdir/$tfile || error "creating to new symlink"
509 }
510 run_test 17d "symlinks: create dangling"
511
512 test_17e() {
513         test_mkdir $DIR/$tdir
514         local foo=$DIR/$tdir/$tfile
515         ln -s $foo $foo || error "create symlink failed"
516         ls -l $foo || error "ls -l failed"
517         ls $foo && error "ls not failed" || true
518 }
519 run_test 17e "symlinks: create recursive symlink (should return error)"
520
521 test_17f() {
522         test_mkdir $DIR/$tdir
523         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
524         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
525         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
526         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
527         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
528         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
529         ls -l  $DIR/$tdir
530 }
531 run_test 17f "symlinks: long and very long symlink name"
532
533 # str_repeat(S, N) generate a string that is string S repeated N times
534 str_repeat() {
535         local s=$1
536         local n=$2
537         local ret=''
538         while [ $((n -= 1)) -ge 0 ]; do
539                 ret=$ret$s
540         done
541         echo $ret
542 }
543
544 # Long symlinks and LU-2241
545 test_17g() {
546         test_mkdir $DIR/$tdir
547         local TESTS="59 60 61 4094 4095"
548
549         # Fix for inode size boundary in 2.1.4
550         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
551                 TESTS="4094 4095"
552
553         # Patch not applied to 2.2 or 2.3 branches
554         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
555         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
556                 TESTS="4094 4095"
557
558         # skip long symlink name for rhel6.5.
559         # rhel6.5 has a limit (PATH_MAX - sizeof(struct filename))
560         grep -q '6.5' /etc/redhat-release &>/dev/null &&
561                 TESTS="59 60 61 4062 4063"
562
563         for i in $TESTS; do
564                 local SYMNAME=$(str_repeat 'x' $i)
565                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
566                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
567         done
568 }
569 run_test 17g "symlinks: really long symlink name and inode boundaries"
570
571 test_17h() { #bug 17378
572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
573         remote_mds_nodsh && skip "remote MDS with nodsh"
574
575         local mdt_idx
576
577         test_mkdir $DIR/$tdir
578         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
579         $LFS setstripe -c -1 $DIR/$tdir
580         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
581         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
582         touch $DIR/$tdir/$tfile || true
583 }
584 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
585
586 test_17i() { #bug 20018
587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
588         remote_mds_nodsh && skip "remote MDS with nodsh"
589
590         local foo=$DIR/$tdir/$tfile
591         local mdt_idx
592
593         test_mkdir -c1 $DIR/$tdir
594         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
595         ln -s $foo $foo || error "create symlink failed"
596 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
597         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
598         ls -l $foo && error "error not detected"
599         return 0
600 }
601 run_test 17i "don't panic on short symlink (should return error)"
602
603 test_17k() { #bug 22301
604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
605         [[ -z "$(which rsync 2>/dev/null)" ]] &&
606                 skip "no rsync command"
607         rsync --help | grep -q xattr ||
608                 skip_env "$(rsync --version | head -n1) does not support xattrs"
609         test_mkdir $DIR/$tdir
610         test_mkdir $DIR/$tdir.new
611         touch $DIR/$tdir/$tfile
612         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
613         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
614                 error "rsync failed with xattrs enabled"
615 }
616 run_test 17k "symlinks: rsync with xattrs enabled"
617
618 test_17l() { # LU-279
619         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
620                 skip "no getfattr command"
621
622         test_mkdir $DIR/$tdir
623         touch $DIR/$tdir/$tfile
624         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
625         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
626                 # -h to not follow symlinks. -m '' to list all the xattrs.
627                 # grep to remove first line: '# file: $path'.
628                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
629                 do
630                         lgetxattr_size_check $path $xattr ||
631                                 error "lgetxattr_size_check $path $xattr failed"
632                 done
633         done
634 }
635 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
636
637 # LU-1540
638 test_17m() {
639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
640         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
641         remote_mds_nodsh && skip "remote MDS with nodsh"
642         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
643         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
644                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
645
646         local short_sym="0123456789"
647         local wdir=$DIR/$tdir
648         local i
649
650         test_mkdir $wdir
651         long_sym=$short_sym
652         # create a long symlink file
653         for ((i = 0; i < 4; ++i)); do
654                 long_sym=${long_sym}${long_sym}
655         done
656
657         echo "create 512 short and long symlink files under $wdir"
658         for ((i = 0; i < 256; ++i)); do
659                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
660                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
661         done
662
663         echo "erase them"
664         rm -f $wdir/*
665         sync
666         wait_delete_completed
667
668         echo "recreate the 512 symlink files with a shorter string"
669         for ((i = 0; i < 512; ++i)); do
670                 # rewrite the symlink file with a shorter string
671                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
672                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
673         done
674
675         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
676         local devname=$(mdsdevname $mds_index)
677
678         echo "stop and checking mds${mds_index}:"
679         # e2fsck should not return error
680         stop mds${mds_index}
681         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
682         rc=$?
683
684         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
685                 error "start mds${mds_index} failed"
686         df $MOUNT > /dev/null 2>&1
687         [ $rc -eq 0 ] ||
688                 error "e2fsck detected error for short/long symlink: rc=$rc"
689         rm -f $wdir/*
690 }
691 run_test 17m "run e2fsck against MDT which contains short/long symlink"
692
693 check_fs_consistency_17n() {
694         local mdt_index
695         local rc=0
696
697         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
698         # so it only check MDT1/MDT2 instead of all of MDTs.
699         for mdt_index in 1 2; do
700                 local devname=$(mdsdevname $mdt_index)
701                 # e2fsck should not return error
702                 stop mds${mdt_index}
703                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
704                         rc=$((rc + $?))
705
706                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
707                         error "mount mds$mdt_index failed"
708                 df $MOUNT > /dev/null 2>&1
709         done
710         return $rc
711 }
712
713 test_17n() {
714         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
716         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
717         remote_mds_nodsh && skip "remote MDS with nodsh"
718         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
719         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
720                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
721
722         local i
723
724         test_mkdir $DIR/$tdir
725         for ((i=0; i<10; i++)); do
726                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
727                         error "create remote dir error $i"
728                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
729                         error "create files under remote dir failed $i"
730         done
731
732         check_fs_consistency_17n ||
733                 error "e2fsck report error after create files under remote dir"
734
735         for ((i = 0; i < 10; i++)); do
736                 rm -rf $DIR/$tdir/remote_dir_${i} ||
737                         error "destroy remote dir error $i"
738         done
739
740         check_fs_consistency_17n ||
741                 error "e2fsck report error after unlink files under remote dir"
742
743         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
744                 skip "lustre < 2.4.50 does not support migrate mv"
745
746         for ((i = 0; i < 10; i++)); do
747                 mkdir -p $DIR/$tdir/remote_dir_${i}
748                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
749                         error "create files under remote dir failed $i"
750                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
751                         error "migrate remote dir error $i"
752         done
753         check_fs_consistency_17n || error "e2fsck report error after migration"
754
755         for ((i = 0; i < 10; i++)); do
756                 rm -rf $DIR/$tdir/remote_dir_${i} ||
757                         error "destroy remote dir error $i"
758         done
759
760         check_fs_consistency_17n || error "e2fsck report error after unlink"
761 }
762 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
763
764 test_17o() {
765         remote_mds_nodsh && skip "remote MDS with nodsh"
766         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
767                 skip "Need MDS version at least 2.3.64"
768
769         local wdir=$DIR/${tdir}o
770         local mdt_index
771         local rc=0
772
773         test_mkdir $wdir
774         touch $wdir/$tfile
775         mdt_index=$($LFS getstripe -m $wdir/$tfile)
776         mdt_index=$((mdt_index + 1))
777
778         cancel_lru_locks mdc
779         #fail mds will wait the failover finish then set
780         #following fail_loc to avoid interfer the recovery process.
781         fail mds${mdt_index}
782
783         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
784         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
785         ls -l $wdir/$tfile && rc=1
786         do_facet mds${mdt_index} lctl set_param fail_loc=0
787         [[ $rc -eq 0 ]] || error "stat file should fail"
788 }
789 run_test 17o "stat file with incompat LMA feature"
790
791 test_18() {
792         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
793         ls $DIR || error "Failed to ls $DIR: $?"
794 }
795 run_test 18 "touch .../f ; ls ... =============================="
796
797 test_19a() {
798         touch $DIR/$tfile
799         ls -l $DIR
800         rm $DIR/$tfile
801         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
802 }
803 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
804
805 test_19b() {
806         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
807 }
808 run_test 19b "ls -l .../f19 (should return error) =============="
809
810 test_19c() {
811         [ $RUNAS_ID -eq $UID ] &&
812                 skip_env "RUNAS_ID = UID = $UID -- skipping"
813
814         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
815 }
816 run_test 19c "$RUNAS touch .../f19 (should return error) =="
817
818 test_19d() {
819         cat $DIR/f19 && error || true
820 }
821 run_test 19d "cat .../f19 (should return error) =============="
822
823 test_20() {
824         touch $DIR/$tfile
825         rm $DIR/$tfile
826         touch $DIR/$tfile
827         rm $DIR/$tfile
828         touch $DIR/$tfile
829         rm $DIR/$tfile
830         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
831 }
832 run_test 20 "touch .../f ; ls -l ..."
833
834 test_21() {
835         test_mkdir $DIR/$tdir
836         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
837         ln -s dangle $DIR/$tdir/link
838         echo foo >> $DIR/$tdir/link
839         cat $DIR/$tdir/dangle
840         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
841         $CHECKSTAT -f -t file $DIR/$tdir/link ||
842                 error "$tdir/link not linked to a file"
843 }
844 run_test 21 "write to dangling link"
845
846 test_22() {
847         local wdir=$DIR/$tdir
848         test_mkdir $wdir
849         chown $RUNAS_ID:$RUNAS_GID $wdir
850         (cd $wdir || error "cd $wdir failed";
851                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
852                 $RUNAS tar xf -)
853         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
854         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
855         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
856                 error "checkstat -u failed"
857 }
858 run_test 22 "unpack tar archive as non-root user"
859
860 # was test_23
861 test_23a() {
862         test_mkdir $DIR/$tdir
863         local file=$DIR/$tdir/$tfile
864
865         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
866         openfile -f O_CREAT:O_EXCL $file &&
867                 error "$file recreate succeeded" || true
868 }
869 run_test 23a "O_CREAT|O_EXCL in subdir"
870
871 test_23b() { # bug 18988
872         test_mkdir $DIR/$tdir
873         local file=$DIR/$tdir/$tfile
874
875         rm -f $file
876         echo foo > $file || error "write filed"
877         echo bar >> $file || error "append filed"
878         $CHECKSTAT -s 8 $file || error "wrong size"
879         rm $file
880 }
881 run_test 23b "O_APPEND check"
882
883 # LU-9409, size with O_APPEND and tiny writes
884 test_23c() {
885         local file=$DIR/$tfile
886
887         # single dd
888         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
889         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
890         rm -f $file
891
892         # racing tiny writes
893         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
894         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
895         wait
896         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
897         rm -f $file
898
899         #racing tiny & normal writes
900         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
901         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
902         wait
903         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
904         rm -f $file
905
906         #racing tiny & normal writes 2, ugly numbers
907         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
908         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
909         wait
910         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
911         rm -f $file
912 }
913 run_test 23c "O_APPEND size checks for tiny writes"
914
915 # LU-11069 file offset is correct after appending writes
916 test_23d() {
917         local file=$DIR/$tfile
918         local offset
919
920         echo CentaurHauls > $file
921         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
922         if ((offset != 26)); then
923                 error "wrong offset, expected 26, got '$offset'"
924         fi
925 }
926 run_test 23d "file offset is correct after appending writes"
927
928 # rename sanity
929 test_24a() {
930         echo '-- same directory rename'
931         test_mkdir $DIR/$tdir
932         touch $DIR/$tdir/$tfile.1
933         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
934         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
935 }
936 run_test 24a "rename file to non-existent target"
937
938 test_24b() {
939         test_mkdir $DIR/$tdir
940         touch $DIR/$tdir/$tfile.{1,2}
941         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
942         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
943         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
944 }
945 run_test 24b "rename file to existing target"
946
947 test_24c() {
948         test_mkdir $DIR/$tdir
949         test_mkdir $DIR/$tdir/d$testnum.1
950         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
951         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
952         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
953 }
954 run_test 24c "rename directory to non-existent target"
955
956 test_24d() {
957         test_mkdir -c1 $DIR/$tdir
958         test_mkdir -c1 $DIR/$tdir/d$testnum.1
959         test_mkdir -c1 $DIR/$tdir/d$testnum.2
960         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
961         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
962         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
963 }
964 run_test 24d "rename directory to existing target"
965
966 test_24e() {
967         echo '-- cross directory renames --'
968         test_mkdir $DIR/R5a
969         test_mkdir $DIR/R5b
970         touch $DIR/R5a/f
971         mv $DIR/R5a/f $DIR/R5b/g
972         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
973         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
974 }
975 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
976
977 test_24f() {
978         test_mkdir $DIR/R6a
979         test_mkdir $DIR/R6b
980         touch $DIR/R6a/f $DIR/R6b/g
981         mv $DIR/R6a/f $DIR/R6b/g
982         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
983         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
984 }
985 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
986
987 test_24g() {
988         test_mkdir $DIR/R7a
989         test_mkdir $DIR/R7b
990         test_mkdir $DIR/R7a/d
991         mv $DIR/R7a/d $DIR/R7b/e
992         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
993         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
994 }
995 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
996
997 test_24h() {
998         test_mkdir -c1 $DIR/R8a
999         test_mkdir -c1 $DIR/R8b
1000         test_mkdir -c1 $DIR/R8a/d
1001         test_mkdir -c1 $DIR/R8b/e
1002         mrename $DIR/R8a/d $DIR/R8b/e
1003         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1004         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1005 }
1006 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1007
1008 test_24i() {
1009         echo "-- rename error cases"
1010         test_mkdir $DIR/R9
1011         test_mkdir $DIR/R9/a
1012         touch $DIR/R9/f
1013         mrename $DIR/R9/f $DIR/R9/a
1014         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1015         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1016         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1017 }
1018 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1019
1020 test_24j() {
1021         test_mkdir $DIR/R10
1022         mrename $DIR/R10/f $DIR/R10/g
1023         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1024         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1025         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1026 }
1027 run_test 24j "source does not exist ============================"
1028
1029 test_24k() {
1030         test_mkdir $DIR/R11a
1031         test_mkdir $DIR/R11a/d
1032         touch $DIR/R11a/f
1033         mv $DIR/R11a/f $DIR/R11a/d
1034         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1035         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1036 }
1037 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1038
1039 # bug 2429 - rename foo foo foo creates invalid file
1040 test_24l() {
1041         f="$DIR/f24l"
1042         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1043 }
1044 run_test 24l "Renaming a file to itself ========================"
1045
1046 test_24m() {
1047         f="$DIR/f24m"
1048         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1049         # on ext3 this does not remove either the source or target files
1050         # though the "expected" operation would be to remove the source
1051         $CHECKSTAT -t file ${f} || error "${f} missing"
1052         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1053 }
1054 run_test 24m "Renaming a file to a hard link to itself ========="
1055
1056 test_24n() {
1057     f="$DIR/f24n"
1058     # this stats the old file after it was renamed, so it should fail
1059     touch ${f}
1060     $CHECKSTAT ${f} || error "${f} missing"
1061     mv ${f} ${f}.rename
1062     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1063     $CHECKSTAT -a ${f} || error "${f} exists"
1064 }
1065 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1066
1067 test_24o() {
1068         test_mkdir $DIR/$tdir
1069         rename_many -s random -v -n 10 $DIR/$tdir
1070 }
1071 run_test 24o "rename of files during htree split"
1072
1073 test_24p() {
1074         test_mkdir $DIR/R12a
1075         test_mkdir $DIR/R12b
1076         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1077         mrename $DIR/R12a $DIR/R12b
1078         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1079         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1080         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1081         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1082 }
1083 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1084
1085 cleanup_multiop_pause() {
1086         trap 0
1087         kill -USR1 $MULTIPID
1088 }
1089
1090 test_24q() {
1091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1092
1093         test_mkdir $DIR/R13a
1094         test_mkdir $DIR/R13b
1095         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1096         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1097         MULTIPID=$!
1098
1099         trap cleanup_multiop_pause EXIT
1100         mrename $DIR/R13a $DIR/R13b
1101         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1102         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1103         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1104         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1105         cleanup_multiop_pause
1106         wait $MULTIPID || error "multiop close failed"
1107 }
1108 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1109
1110 test_24r() { #bug 3789
1111         test_mkdir $DIR/R14a
1112         test_mkdir $DIR/R14a/b
1113         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1114         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1115         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1116 }
1117 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1118
1119 test_24s() {
1120         test_mkdir $DIR/R15a
1121         test_mkdir $DIR/R15a/b
1122         test_mkdir $DIR/R15a/b/c
1123         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1124         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1125         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1126 }
1127 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1128 test_24t() {
1129         test_mkdir $DIR/R16a
1130         test_mkdir $DIR/R16a/b
1131         test_mkdir $DIR/R16a/b/c
1132         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1133         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1134         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1135 }
1136 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1137
1138 test_24u() { # bug12192
1139         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1140         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1141 }
1142 run_test 24u "create stripe file"
1143
1144 simple_cleanup_common() {
1145         local rc=0
1146         trap 0
1147         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1148
1149         local start=$SECONDS
1150         rm -rf $DIR/$tdir
1151         rc=$?
1152         wait_delete_completed
1153         echo "cleanup time $((SECONDS - start))"
1154         return $rc
1155 }
1156
1157 max_pages_per_rpc() {
1158         local mdtname="$(printf "MDT%04x" ${1:-0})"
1159         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1160 }
1161
1162 test_24v() {
1163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1164
1165         local nrfiles=${COUNT:-100000}
1166         local fname="$DIR/$tdir/$tfile"
1167
1168         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1169         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1170
1171         test_mkdir "$(dirname $fname)"
1172         # assume MDT0000 has the fewest inodes
1173         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1174         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1175         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1176
1177         trap simple_cleanup_common EXIT
1178
1179         createmany -m "$fname" $nrfiles
1180
1181         cancel_lru_locks mdc
1182         lctl set_param mdc.*.stats clear
1183
1184         # was previously test_24D: LU-6101
1185         # readdir() returns correct number of entries after cursor reload
1186         local num_ls=$(ls $DIR/$tdir | wc -l)
1187         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1188         local num_all=$(ls -a $DIR/$tdir | wc -l)
1189         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1190                 [ $num_all -ne $((nrfiles + 2)) ]; then
1191                         error "Expected $nrfiles files, got $num_ls " \
1192                                 "($num_uniq unique $num_all .&..)"
1193         fi
1194         # LU-5 large readdir
1195         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1196         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1197         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1198         # take into account of overhead in lu_dirpage header and end mark in
1199         # each page, plus one in rpc_num calculation.
1200         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1201         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1202         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1203         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1204         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1205         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1206         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1207         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1208                 error "large readdir doesn't take effect: " \
1209                       "$mds_readpage should be about $rpc_max"
1210
1211         simple_cleanup_common
1212 }
1213 run_test 24v "list large directory (test hash collision, b=17560)"
1214
1215 test_24w() { # bug21506
1216         SZ1=234852
1217         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1218         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1219         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1220         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1221         [[ "$SZ1" -eq "$SZ2" ]] ||
1222                 error "Error reading at the end of the file $tfile"
1223 }
1224 run_test 24w "Reading a file larger than 4Gb"
1225
1226 test_24x() {
1227         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1229         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1230                 skip "Need MDS version at least 2.7.56"
1231
1232         local MDTIDX=1
1233         local remote_dir=$DIR/$tdir/remote_dir
1234
1235         test_mkdir $DIR/$tdir
1236         $LFS mkdir -i $MDTIDX $remote_dir ||
1237                 error "create remote directory failed"
1238
1239         test_mkdir $DIR/$tdir/src_dir
1240         touch $DIR/$tdir/src_file
1241         test_mkdir $remote_dir/tgt_dir
1242         touch $remote_dir/tgt_file
1243
1244         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1245                 error "rename dir cross MDT failed!"
1246
1247         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1248                 error "rename file cross MDT failed!"
1249
1250         touch $DIR/$tdir/ln_file
1251         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1252                 error "ln file cross MDT failed"
1253
1254         rm -rf $DIR/$tdir || error "Can not delete directories"
1255 }
1256 run_test 24x "cross MDT rename/link"
1257
1258 test_24y() {
1259         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1261
1262         local remote_dir=$DIR/$tdir/remote_dir
1263         local mdtidx=1
1264
1265         test_mkdir $DIR/$tdir
1266         $LFS mkdir -i $mdtidx $remote_dir ||
1267                 error "create remote directory failed"
1268
1269         test_mkdir $remote_dir/src_dir
1270         touch $remote_dir/src_file
1271         test_mkdir $remote_dir/tgt_dir
1272         touch $remote_dir/tgt_file
1273
1274         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1275                 error "rename subdir in the same remote dir failed!"
1276
1277         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1278                 error "rename files in the same remote dir failed!"
1279
1280         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1281                 error "link files in the same remote dir failed!"
1282
1283         rm -rf $DIR/$tdir || error "Can not delete directories"
1284 }
1285 run_test 24y "rename/link on the same dir should succeed"
1286
1287 test_24z() {
1288         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1289         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1290                 skip "Need MDS version at least 2.12.51"
1291
1292         local index
1293
1294         for index in 0 1; do
1295                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1296                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1297         done
1298
1299         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1300
1301         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1302         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1303
1304         local mdts=$(comma_list $(mdts_nodes))
1305
1306         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1307         stack_trap "do_nodes $mdts $LCTL \
1308                 set_param mdt.*.enable_remote_rename=1" EXIT
1309
1310         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1311
1312         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1313         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1314 }
1315 run_test 24z "cross-MDT rename is done as cp"
1316
1317 test_24A() { # LU-3182
1318         local NFILES=5000
1319
1320         rm -rf $DIR/$tdir
1321         test_mkdir $DIR/$tdir
1322         trap simple_cleanup_common EXIT
1323         createmany -m $DIR/$tdir/$tfile $NFILES
1324         local t=$(ls $DIR/$tdir | wc -l)
1325         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1326         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1327         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1328            [ $v -ne $((NFILES + 2)) ] ; then
1329                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1330         fi
1331
1332         simple_cleanup_common || error "Can not delete directories"
1333 }
1334 run_test 24A "readdir() returns correct number of entries."
1335
1336 test_24B() { # LU-4805
1337         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1338
1339         local count
1340
1341         test_mkdir $DIR/$tdir
1342         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1343                 error "create striped dir failed"
1344
1345         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1346         [ $count -eq 2 ] || error "Expected 2, got $count"
1347
1348         touch $DIR/$tdir/striped_dir/a
1349
1350         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1351         [ $count -eq 3 ] || error "Expected 3, got $count"
1352
1353         touch $DIR/$tdir/striped_dir/.f
1354
1355         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1356         [ $count -eq 4 ] || error "Expected 4, got $count"
1357
1358         rm -rf $DIR/$tdir || error "Can not delete directories"
1359 }
1360 run_test 24B "readdir for striped dir return correct number of entries"
1361
1362 test_24C() {
1363         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1364
1365         mkdir $DIR/$tdir
1366         mkdir $DIR/$tdir/d0
1367         mkdir $DIR/$tdir/d1
1368
1369         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1370                 error "create striped dir failed"
1371
1372         cd $DIR/$tdir/d0/striped_dir
1373
1374         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1375         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1376         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1377
1378         [ "$d0_ino" = "$parent_ino" ] ||
1379                 error ".. wrong, expect $d0_ino, get $parent_ino"
1380
1381         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1382                 error "mv striped dir failed"
1383
1384         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1385
1386         [ "$d1_ino" = "$parent_ino" ] ||
1387                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1388 }
1389 run_test 24C "check .. in striped dir"
1390
1391 test_24E() {
1392         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1394
1395         mkdir -p $DIR/$tdir
1396         mkdir $DIR/$tdir/src_dir
1397         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1398                 error "create remote source failed"
1399
1400         touch $DIR/$tdir/src_dir/src_child/a
1401
1402         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1403                 error "create remote target dir failed"
1404
1405         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1406                 error "create remote target child failed"
1407
1408         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1409                 error "rename dir cross MDT failed!"
1410
1411         find $DIR/$tdir
1412
1413         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1414                 error "src_child still exists after rename"
1415
1416         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1417                 error "missing file(a) after rename"
1418
1419         rm -rf $DIR/$tdir || error "Can not delete directories"
1420 }
1421 run_test 24E "cross MDT rename/link"
1422
1423 test_24F () {
1424         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1425
1426         local repeats=1000
1427         [ "$SLOW" = "no" ] && repeats=100
1428
1429         mkdir -p $DIR/$tdir
1430
1431         echo "$repeats repeats"
1432         for ((i = 0; i < repeats; i++)); do
1433                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1434                 touch $DIR/$tdir/test/a || error "touch fails"
1435                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1436                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1437         done
1438
1439         true
1440 }
1441 run_test 24F "hash order vs readdir (LU-11330)"
1442
1443 test_25a() {
1444         echo '== symlink sanity ============================================='
1445
1446         test_mkdir $DIR/d25
1447         ln -s d25 $DIR/s25
1448         touch $DIR/s25/foo ||
1449                 error "File creation in symlinked directory failed"
1450 }
1451 run_test 25a "create file in symlinked directory ==============="
1452
1453 test_25b() {
1454         [ ! -d $DIR/d25 ] && test_25a
1455         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1456 }
1457 run_test 25b "lookup file in symlinked directory ==============="
1458
1459 test_26a() {
1460         test_mkdir $DIR/d26
1461         test_mkdir $DIR/d26/d26-2
1462         ln -s d26/d26-2 $DIR/s26
1463         touch $DIR/s26/foo || error "File creation failed"
1464 }
1465 run_test 26a "multiple component symlink ======================="
1466
1467 test_26b() {
1468         test_mkdir -p $DIR/$tdir/d26-2
1469         ln -s $tdir/d26-2/foo $DIR/s26-2
1470         touch $DIR/s26-2 || error "File creation failed"
1471 }
1472 run_test 26b "multiple component symlink at end of lookup ======"
1473
1474 test_26c() {
1475         test_mkdir $DIR/d26.2
1476         touch $DIR/d26.2/foo
1477         ln -s d26.2 $DIR/s26.2-1
1478         ln -s s26.2-1 $DIR/s26.2-2
1479         ln -s s26.2-2 $DIR/s26.2-3
1480         chmod 0666 $DIR/s26.2-3/foo
1481 }
1482 run_test 26c "chain of symlinks"
1483
1484 # recursive symlinks (bug 439)
1485 test_26d() {
1486         ln -s d26-3/foo $DIR/d26-3
1487 }
1488 run_test 26d "create multiple component recursive symlink"
1489
1490 test_26e() {
1491         [ ! -h $DIR/d26-3 ] && test_26d
1492         rm $DIR/d26-3
1493 }
1494 run_test 26e "unlink multiple component recursive symlink"
1495
1496 # recursive symlinks (bug 7022)
1497 test_26f() {
1498         test_mkdir $DIR/$tdir
1499         test_mkdir $DIR/$tdir/$tfile
1500         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1501         test_mkdir -p lndir/bar1
1502         test_mkdir $DIR/$tdir/$tfile/$tfile
1503         cd $tfile                || error "cd $tfile failed"
1504         ln -s .. dotdot          || error "ln dotdot failed"
1505         ln -s dotdot/lndir lndir || error "ln lndir failed"
1506         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1507         output=`ls $tfile/$tfile/lndir/bar1`
1508         [ "$output" = bar1 ] && error "unexpected output"
1509         rm -r $tfile             || error "rm $tfile failed"
1510         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1511 }
1512 run_test 26f "rm -r of a directory which has recursive symlink"
1513
1514 test_27a() {
1515         test_mkdir $DIR/$tdir
1516         $LFS getstripe $DIR/$tdir
1517         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1518         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1519         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1520 }
1521 run_test 27a "one stripe file"
1522
1523 test_27b() {
1524         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1525
1526         test_mkdir $DIR/$tdir
1527         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1528         $LFS getstripe -c $DIR/$tdir/$tfile
1529         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1530                 error "two-stripe file doesn't have two stripes"
1531
1532         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1533 }
1534 run_test 27b "create and write to two stripe file"
1535
1536 test_27d() {
1537         test_mkdir $DIR/$tdir
1538         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1539                 error "setstripe failed"
1540         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1541         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1542 }
1543 run_test 27d "create file with default settings"
1544
1545 test_27e() {
1546         # LU-5839 adds check for existed layout before setting it
1547         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1548                 skip "Need MDS version at least 2.7.56"
1549
1550         test_mkdir $DIR/$tdir
1551         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1552         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1553         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1554 }
1555 run_test 27e "setstripe existing file (should return error)"
1556
1557 test_27f() {
1558         test_mkdir $DIR/$tdir
1559         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1560                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1561         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1562                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1563         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1564         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1565 }
1566 run_test 27f "setstripe with bad stripe size (should return error)"
1567
1568 test_27g() {
1569         test_mkdir $DIR/$tdir
1570         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1571         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1572                 error "$DIR/$tdir/$tfile has object"
1573 }
1574 run_test 27g "$LFS getstripe with no objects"
1575
1576 test_27i() {
1577         test_mkdir $DIR/$tdir
1578         touch $DIR/$tdir/$tfile || error "touch failed"
1579         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1580                 error "missing objects"
1581 }
1582 run_test 27i "$LFS getstripe with some objects"
1583
1584 test_27j() {
1585         test_mkdir $DIR/$tdir
1586         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1587                 error "setstripe failed" || true
1588 }
1589 run_test 27j "setstripe with bad stripe offset (should return error)"
1590
1591 test_27k() { # bug 2844
1592         test_mkdir $DIR/$tdir
1593         local file=$DIR/$tdir/$tfile
1594         local ll_max_blksize=$((4 * 1024 * 1024))
1595         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1596         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1597         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1598         dd if=/dev/zero of=$file bs=4k count=1
1599         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1600         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1601 }
1602 run_test 27k "limit i_blksize for broken user apps"
1603
1604 test_27l() {
1605         mcreate $DIR/$tfile || error "creating file"
1606         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1607                 error "setstripe should have failed" || true
1608 }
1609 run_test 27l "check setstripe permissions (should return error)"
1610
1611 test_27m() {
1612         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1613
1614         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1615                    head -n1)
1616         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1617                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1618         fi
1619         trap simple_cleanup_common EXIT
1620         test_mkdir $DIR/$tdir
1621         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1622         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1623                 error "dd should fill OST0"
1624         i=2
1625         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1626                 i=$((i + 1))
1627                 [ $i -gt 256 ] && break
1628         done
1629         i=$((i + 1))
1630         touch $DIR/$tdir/$tfile.$i
1631         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1632             awk '{print $1}'| grep -w "0") ] &&
1633                 error "OST0 was full but new created file still use it"
1634         i=$((i + 1))
1635         touch $DIR/$tdir/$tfile.$i
1636         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1637             awk '{print $1}'| grep -w "0") ] &&
1638                 error "OST0 was full but new created file still use it"
1639         simple_cleanup_common
1640 }
1641 run_test 27m "create file while OST0 was full"
1642
1643 sleep_maxage() {
1644         local delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1645                       awk '{ print $1 * 2; exit; }')
1646         sleep $delay
1647 }
1648
1649 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1650 # if the OST isn't full anymore.
1651 reset_enospc() {
1652         local OSTIDX=${1:-""}
1653
1654         local list=$(comma_list $(osts_nodes))
1655         [ "$OSTIDX" ] && list=$(facet_host ost$((OSTIDX + 1)))
1656
1657         do_nodes $list lctl set_param fail_loc=0
1658         sync    # initiate all OST_DESTROYs from MDS to OST
1659         sleep_maxage
1660 }
1661
1662 exhaust_precreations() {
1663         local OSTIDX=$1
1664         local FAILLOC=$2
1665         local FAILIDX=${3:-$OSTIDX}
1666         local ofacet=ost$((OSTIDX + 1))
1667
1668         test_mkdir -p -c1 $DIR/$tdir
1669         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1670         local mfacet=mds$((mdtidx + 1))
1671         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1672
1673         local OST=$(ostname_from_index $OSTIDX)
1674
1675         # on the mdt's osc
1676         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1677         local last_id=$(do_facet $mfacet lctl get_param -n \
1678                         osc.$mdtosc_proc1.prealloc_last_id)
1679         local next_id=$(do_facet $mfacet lctl get_param -n \
1680                         osc.$mdtosc_proc1.prealloc_next_id)
1681
1682         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1683         do_facet $mfacet lctl get_param osc.$mdtosc_proc2.prealloc*
1684
1685         test_mkdir -p $DIR/$tdir/${OST}
1686         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1687 #define OBD_FAIL_OST_ENOSPC              0x215
1688         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1689         echo "Creating to objid $last_id on ost $OST..."
1690         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1691         do_facet $mfacet lctl get_param osc.$mdtosc_proc2.prealloc*
1692         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1693         sleep_maxage
1694 }
1695
1696 exhaust_all_precreations() {
1697         local i
1698         for (( i=0; i < OSTCOUNT; i++ )) ; do
1699                 exhaust_precreations $i $1 -1
1700         done
1701 }
1702
1703 test_27n() {
1704         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1706         remote_mds_nodsh && skip "remote MDS with nodsh"
1707         remote_ost_nodsh && skip "remote OST with nodsh"
1708
1709         reset_enospc
1710         rm -f $DIR/$tdir/$tfile
1711         exhaust_precreations 0 0x80000215
1712         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1713         touch $DIR/$tdir/$tfile || error "touch failed"
1714         $LFS getstripe $DIR/$tdir/$tfile
1715         reset_enospc
1716 }
1717 run_test 27n "create file with some full OSTs"
1718
1719 test_27o() {
1720         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1722         remote_mds_nodsh && skip "remote MDS with nodsh"
1723         remote_ost_nodsh && skip "remote OST with nodsh"
1724
1725         reset_enospc
1726         rm -f $DIR/$tdir/$tfile
1727         exhaust_all_precreations 0x215
1728
1729         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1730
1731         reset_enospc
1732         rm -rf $DIR/$tdir/*
1733 }
1734 run_test 27o "create file with all full OSTs (should error)"
1735
1736 test_27p() {
1737         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1739         remote_mds_nodsh && skip "remote MDS with nodsh"
1740         remote_ost_nodsh && skip "remote OST with nodsh"
1741
1742         reset_enospc
1743         rm -f $DIR/$tdir/$tfile
1744         test_mkdir $DIR/$tdir
1745
1746         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1747         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1748         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1749
1750         exhaust_precreations 0 0x80000215
1751         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1752         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1753         $LFS getstripe $DIR/$tdir/$tfile
1754
1755         reset_enospc
1756 }
1757 run_test 27p "append to a truncated file with some full OSTs"
1758
1759 test_27q() {
1760         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1762         remote_mds_nodsh && skip "remote MDS with nodsh"
1763         remote_ost_nodsh && skip "remote OST with nodsh"
1764
1765         reset_enospc
1766         rm -f $DIR/$tdir/$tfile
1767
1768         test_mkdir $DIR/$tdir
1769         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1770         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1771                 error "truncate $DIR/$tdir/$tfile failed"
1772         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1773
1774         exhaust_all_precreations 0x215
1775
1776         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1777         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1778
1779         reset_enospc
1780 }
1781 run_test 27q "append to truncated file with all OSTs full (should error)"
1782
1783 test_27r() {
1784         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1786         remote_mds_nodsh && skip "remote MDS with nodsh"
1787         remote_ost_nodsh && skip "remote OST with nodsh"
1788
1789         reset_enospc
1790         rm -f $DIR/$tdir/$tfile
1791         exhaust_precreations 0 0x80000215
1792
1793         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1794
1795         reset_enospc
1796 }
1797 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1798
1799 test_27s() { # bug 10725
1800         test_mkdir $DIR/$tdir
1801         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1802         local stripe_count=0
1803         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1804         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1805                 error "stripe width >= 2^32 succeeded" || true
1806
1807 }
1808 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1809
1810 test_27t() { # bug 10864
1811         WDIR=$(pwd)
1812         WLFS=$(which lfs)
1813         cd $DIR
1814         touch $tfile
1815         $WLFS getstripe $tfile
1816         cd $WDIR
1817 }
1818 run_test 27t "check that utils parse path correctly"
1819
1820 test_27u() { # bug 4900
1821         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1822         remote_mds_nodsh && skip "remote MDS with nodsh"
1823
1824         local index
1825         local list=$(comma_list $(mdts_nodes))
1826
1827 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1828         do_nodes $list $LCTL set_param fail_loc=0x139
1829         test_mkdir -p $DIR/$tdir
1830         trap simple_cleanup_common EXIT
1831         createmany -o $DIR/$tdir/t- 1000
1832         do_nodes $list $LCTL set_param fail_loc=0
1833
1834         TLOG=$TMP/$tfile.getstripe
1835         $LFS getstripe $DIR/$tdir > $TLOG
1836         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1837         unlinkmany $DIR/$tdir/t- 1000
1838         trap 0
1839         [[ $OBJS -gt 0 ]] &&
1840                 error "$OBJS objects created on OST-0. See $TLOG" ||
1841                 rm -f $TLOG
1842 }
1843 run_test 27u "skip object creation on OSC w/o objects"
1844
1845 test_27v() { # bug 4900
1846         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1848         remote_mds_nodsh && skip "remote MDS with nodsh"
1849         remote_ost_nodsh && skip "remote OST with nodsh"
1850
1851         exhaust_all_precreations 0x215
1852         reset_enospc
1853
1854         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1855
1856         touch $DIR/$tdir/$tfile
1857         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
1858         # all except ost1
1859         for (( i=1; i < OSTCOUNT; i++ )); do
1860                 do_facet ost$i lctl set_param fail_loc=0x705
1861         done
1862         local START=`date +%s`
1863         createmany -o $DIR/$tdir/$tfile 32
1864
1865         local FINISH=`date +%s`
1866         local TIMEOUT=`lctl get_param -n timeout`
1867         local PROCESS=$((FINISH - START))
1868         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
1869                error "$FINISH - $START >= $TIMEOUT / 2"
1870         sleep $((TIMEOUT / 2 - PROCESS))
1871         reset_enospc
1872 }
1873 run_test 27v "skip object creation on slow OST"
1874
1875 test_27w() { # bug 10997
1876         test_mkdir $DIR/$tdir
1877         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
1878         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
1879                 error "stripe size $size != 65536" || true
1880         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
1881                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
1882 }
1883 run_test 27w "check $LFS setstripe -S and getstrip -d options"
1884
1885 test_27wa() {
1886         [[ $OSTCOUNT -lt 2 ]] &&
1887                 skip_env "skipping multiple stripe count/offset test"
1888
1889         test_mkdir $DIR/$tdir
1890         for i in $(seq 1 $OSTCOUNT); do
1891                 offset=$((i - 1))
1892                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
1893                         error "setstripe -c $i -i $offset failed"
1894                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
1895                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
1896                 [ $count -ne $i ] && error "stripe count $count != $i" || true
1897                 [ $index -ne $offset ] &&
1898                         error "stripe offset $index != $offset" || true
1899         done
1900 }
1901 run_test 27wa "check $LFS setstripe -c -i options"
1902
1903 test_27x() {
1904         remote_ost_nodsh && skip "remote OST with nodsh"
1905         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1907
1908         OFFSET=$(($OSTCOUNT - 1))
1909         OSTIDX=0
1910         local OST=$(ostname_from_index $OSTIDX)
1911
1912         test_mkdir $DIR/$tdir
1913         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
1914         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
1915         sleep_maxage
1916         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
1917         for i in $(seq 0 $OFFSET); do
1918                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
1919                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
1920                 error "OST0 was degraded but new created file still use it"
1921         done
1922         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
1923 }
1924 run_test 27x "create files while OST0 is degraded"
1925
1926 test_27y() {
1927         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1928         remote_mds_nodsh && skip "remote MDS with nodsh"
1929         remote_ost_nodsh && skip "remote OST with nodsh"
1930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1931
1932         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
1933         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
1934                 osc.$mdtosc.prealloc_last_id)
1935         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
1936                 osc.$mdtosc.prealloc_next_id)
1937         local fcount=$((last_id - next_id))
1938         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
1939         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
1940
1941         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
1942                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
1943         local OST_DEACTIVE_IDX=-1
1944         local OSC
1945         local OSTIDX
1946         local OST
1947
1948         for OSC in $MDS_OSCS; do
1949                 OST=$(osc_to_ost $OSC)
1950                 OSTIDX=$(index_from_ostuuid $OST)
1951                 if [ $OST_DEACTIVE_IDX == -1 ]; then
1952                         OST_DEACTIVE_IDX=$OSTIDX
1953                 fi
1954                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
1955                         echo $OSC "is Deactivated:"
1956                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
1957                 fi
1958         done
1959
1960         OSTIDX=$(index_from_ostuuid $OST)
1961         test_mkdir $DIR/$tdir
1962         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
1963
1964         for OSC in $MDS_OSCS; do
1965                 OST=$(osc_to_ost $OSC)
1966                 OSTIDX=$(index_from_ostuuid $OST)
1967                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
1968                         echo $OST "is degraded:"
1969                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
1970                                                 obdfilter.$OST.degraded=1
1971                 fi
1972         done
1973
1974         sleep_maxage
1975         createmany -o $DIR/$tdir/$tfile $fcount
1976
1977         for OSC in $MDS_OSCS; do
1978                 OST=$(osc_to_ost $OSC)
1979                 OSTIDX=$(index_from_ostuuid $OST)
1980                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
1981                         echo $OST "is recovered from degraded:"
1982                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
1983                                                 obdfilter.$OST.degraded=0
1984                 else
1985                         do_facet $SINGLEMDS lctl --device %$OSC activate
1986                 fi
1987         done
1988
1989         # all osp devices get activated, hence -1 stripe count restored
1990         local stripe_count=0
1991
1992         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
1993         # devices get activated.
1994         sleep_maxage
1995         $LFS setstripe -c -1 $DIR/$tfile
1996         stripe_count=$($LFS getstripe -c $DIR/$tfile)
1997         rm -f $DIR/$tfile
1998         [ $stripe_count -ne $OSTCOUNT ] &&
1999                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2000         return 0
2001 }
2002 run_test 27y "create files while OST0 is degraded and the rest inactive"
2003
2004 check_seq_oid()
2005 {
2006         log "check file $1"
2007
2008         lmm_count=$($LFS getstripe -c $1)
2009         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2010         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2011
2012         local old_ifs="$IFS"
2013         IFS=$'[:]'
2014         fid=($($LFS path2fid $1))
2015         IFS="$old_ifs"
2016
2017         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2018         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2019
2020         # compare lmm_seq and lu_fid->f_seq
2021         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2022         # compare lmm_object_id and lu_fid->oid
2023         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2024
2025         # check the trusted.fid attribute of the OST objects of the file
2026         local have_obdidx=false
2027         local stripe_nr=0
2028         $LFS getstripe $1 | while read obdidx oid hex seq; do
2029                 # skip lines up to and including "obdidx"
2030                 [ -z "$obdidx" ] && break
2031                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2032                 $have_obdidx || continue
2033
2034                 local ost=$((obdidx + 1))
2035                 local dev=$(ostdevname $ost)
2036                 local oid_hex
2037
2038                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2039
2040                 seq=$(echo $seq | sed -e "s/^0x//g")
2041                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2042                         oid_hex=$(echo $oid)
2043                 else
2044                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2045                 fi
2046                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2047
2048                 local ff=""
2049                 #
2050                 # Don't unmount/remount the OSTs if we don't need to do that.
2051                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2052                 # update too, until that use mount/ll_decode_filter_fid/mount.
2053                 # Re-enable when debugfs will understand new filter_fid.
2054                 #
2055                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2056                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2057                                 $dev 2>/dev/null" | grep "parent=")
2058                 fi
2059                 if [ -z "$ff" ]; then
2060                         stop ost$ost
2061                         mount_fstype ost$ost
2062                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2063                                 $(facet_mntpt ost$ost)/$obj_file)
2064                         unmount_fstype ost$ost
2065                         start ost$ost $dev $OST_MOUNT_OPTS
2066                         clients_up
2067                 fi
2068
2069                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2070
2071                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2072
2073                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2074                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2075                 #
2076                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2077                 #       stripe_size=1048576 component_id=1 component_start=0 \
2078                 #       component_end=33554432
2079                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2080                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2081                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2082                 local ff_pstripe
2083                 if grep -q 'stripe=' <<<$ff; then
2084                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2085                 else
2086                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2087                         # into f_ver in this case.  See comment on ff_parent.
2088                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2089                 fi
2090
2091                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2092                 [ $ff_pseq = $lmm_seq ] ||
2093                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2094                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2095                 [ $ff_poid = $lmm_oid ] ||
2096                         error "FF parent OID $ff_poid != $lmm_oid"
2097                 (($ff_pstripe == $stripe_nr)) ||
2098                         error "FF stripe $ff_pstripe != $stripe_nr"
2099
2100                 stripe_nr=$((stripe_nr + 1))
2101                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2102                         continue
2103                 if grep -q 'stripe_count=' <<<$ff; then
2104                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2105                                             -e 's/ .*//' <<<$ff)
2106                         [ $lmm_count = $ff_scnt ] ||
2107                                 error "FF stripe count $lmm_count != $ff_scnt"
2108                 fi
2109         done
2110 }
2111
2112 test_27z() {
2113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2114         remote_ost_nodsh && skip "remote OST with nodsh"
2115
2116         test_mkdir $DIR/$tdir
2117         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2118                 { error "setstripe -c -1 failed"; return 1; }
2119         # We need to send a write to every object to get parent FID info set.
2120         # This _should_ also work for setattr, but does not currently.
2121         # touch $DIR/$tdir/$tfile-1 ||
2122         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2123                 { error "dd $tfile-1 failed"; return 2; }
2124         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2125                 { error "setstripe -c -1 failed"; return 3; }
2126         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2127                 { error "dd $tfile-2 failed"; return 4; }
2128
2129         # make sure write RPCs have been sent to OSTs
2130         sync; sleep 5; sync
2131
2132         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2133         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2134 }
2135 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2136
2137 test_27A() { # b=19102
2138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2139
2140         save_layout_restore_at_exit $MOUNT
2141         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2142         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2143                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2144         local default_size=$($LFS getstripe -S $MOUNT)
2145         local default_offset=$($LFS getstripe -i $MOUNT)
2146         local dsize=$(do_facet $SINGLEMDS \
2147                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2148         [ $default_size -eq $dsize ] ||
2149                 error "stripe size $default_size != $dsize"
2150         [ $default_offset -eq -1 ] ||
2151                 error "stripe offset $default_offset != -1"
2152 }
2153 run_test 27A "check filesystem-wide default LOV EA values"
2154
2155 test_27B() { # LU-2523
2156         test_mkdir $DIR/$tdir
2157         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2158         touch $DIR/$tdir/f0
2159         # open f1 with O_LOV_DELAY_CREATE
2160         # rename f0 onto f1
2161         # call setstripe ioctl on open file descriptor for f1
2162         # close
2163         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2164                 $DIR/$tdir/f0
2165
2166         rm -f $DIR/$tdir/f1
2167         # open f1 with O_LOV_DELAY_CREATE
2168         # unlink f1
2169         # call setstripe ioctl on open file descriptor for f1
2170         # close
2171         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2172
2173         # Allow multiop to fail in imitation of NFS's busted semantics.
2174         true
2175 }
2176 run_test 27B "call setstripe on open unlinked file/rename victim"
2177
2178 test_27C() { #LU-2871
2179         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2180
2181         declare -a ost_idx
2182         local index
2183         local found
2184         local i
2185         local j
2186
2187         test_mkdir $DIR/$tdir
2188         cd $DIR/$tdir
2189         for i in $(seq 0 $((OSTCOUNT - 1))); do
2190                 # set stripe across all OSTs starting from OST$i
2191                 $LFS setstripe -i $i -c -1 $tfile$i
2192                 # get striping information
2193                 ost_idx=($($LFS getstripe $tfile$i |
2194                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2195                 echo ${ost_idx[@]}
2196
2197                 # check the layout
2198                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2199                         error "${#ost_idx[@]} != $OSTCOUNT"
2200
2201                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2202                         found=0
2203                         for j in $(echo ${ost_idx[@]}); do
2204                                 if [ $index -eq $j ]; then
2205                                         found=1
2206                                         break
2207                                 fi
2208                         done
2209                         [ $found = 1 ] ||
2210                                 error "Can not find $index in ${ost_idx[@]}"
2211                 done
2212         done
2213 }
2214 run_test 27C "check full striping across all OSTs"
2215
2216 test_27D() {
2217         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2218         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2219         remote_mds_nodsh && skip "remote MDS with nodsh"
2220
2221         local POOL=${POOL:-testpool}
2222         local first_ost=0
2223         local last_ost=$(($OSTCOUNT - 1))
2224         local ost_step=1
2225         local ost_list=$(seq $first_ost $ost_step $last_ost)
2226         local ost_range="$first_ost $last_ost $ost_step"
2227
2228         if ! combined_mgs_mds ; then
2229                 mount_mgs_client
2230         fi
2231
2232         test_mkdir $DIR/$tdir
2233         pool_add $POOL || error "pool_add failed"
2234         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2235
2236         local skip27D
2237         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2238                 skip27D+="-s 29"
2239         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2240                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2241                         skip27D+=" -s 30,31"
2242         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2243                 error "llapi_layout_test failed"
2244
2245         destroy_test_pools || error "destroy test pools failed"
2246
2247         if ! combined_mgs_mds ; then
2248                 umount_mgs_client
2249         fi
2250 }
2251 run_test 27D "validate llapi_layout API"
2252
2253 # Verify that default_easize is increased from its initial value after
2254 # accessing a widely striped file.
2255 test_27E() {
2256         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2257         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2258                 skip "client does not have LU-3338 fix"
2259
2260         # 72 bytes is the minimum space required to store striping
2261         # information for a file striped across one OST:
2262         # (sizeof(struct lov_user_md_v3) +
2263         #  sizeof(struct lov_user_ost_data_v1))
2264         local min_easize=72
2265         $LCTL set_param -n llite.*.default_easize $min_easize ||
2266                 error "lctl set_param failed"
2267         local easize=$($LCTL get_param -n llite.*.default_easize)
2268
2269         [ $easize -eq $min_easize ] ||
2270                 error "failed to set default_easize"
2271
2272         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2273                 error "setstripe failed"
2274         cat $DIR/$tfile
2275         rm $DIR/$tfile
2276
2277         easize=$($LCTL get_param -n llite.*.default_easize)
2278
2279         [ $easize -gt $min_easize ] ||
2280                 error "default_easize not updated"
2281 }
2282 run_test 27E "check that default extended attribute size properly increases"
2283
2284 test_27F() { # LU-5346/LU-7975
2285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2286         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2287         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2288                 skip "Need MDS version at least 2.8.51"
2289         remote_ost_nodsh && skip "remote OST with nodsh"
2290
2291         test_mkdir $DIR/$tdir
2292         rm -f $DIR/$tdir/f0
2293         $LFS setstripe -c 2 $DIR/$tdir
2294
2295         # stop all OSTs to reproduce situation for LU-7975 ticket
2296         for num in $(seq $OSTCOUNT); do
2297                 stop ost$num
2298         done
2299
2300         # open/create f0 with O_LOV_DELAY_CREATE
2301         # truncate f0 to a non-0 size
2302         # close
2303         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2304
2305         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2306         # open/write it again to force delayed layout creation
2307         cat /etc/hosts > $DIR/$tdir/f0 &
2308         catpid=$!
2309
2310         # restart OSTs
2311         for num in $(seq $OSTCOUNT); do
2312                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2313                         error "ost$num failed to start"
2314         done
2315
2316         wait $catpid || error "cat failed"
2317
2318         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2319         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2320                 error "wrong stripecount"
2321
2322 }
2323 run_test 27F "Client resend delayed layout creation with non-zero size"
2324
2325 test_27G() { #LU-10629
2326         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2327                 skip "Need MDS version at least 2.11.51"
2328         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2329         remote_mds_nodsh && skip "remote MDS with nodsh"
2330         local POOL=${POOL:-testpool}
2331         local ostrange="0 0 1"
2332
2333         test_mkdir $DIR/$tdir
2334         pool_add $POOL || error "pool_add failed"
2335         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2336         $LFS setstripe -p $POOL $DIR/$tdir
2337
2338         local pool=$($LFS getstripe -p $DIR/$tdir)
2339
2340         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2341
2342         $LFS setstripe -d $DIR/$tdir
2343
2344         pool=$($LFS getstripe -p $DIR/$tdir)
2345
2346         rmdir $DIR/$tdir
2347
2348         [ -z "$pool" ] || error "'$pool' is not empty"
2349 }
2350 run_test 27G "Clear OST pool from stripe"
2351
2352 test_27H() {
2353         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2354                 skip "Need MDS version newer than 2.11.54"
2355         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2356         test_mkdir $DIR/$tdir
2357         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2358         touch $DIR/$tdir/$tfile
2359         $LFS getstripe -c $DIR/$tdir/$tfile
2360         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2361                 error "two-stripe file doesn't have two stripes"
2362
2363         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2364         $LFS getstripe -y $DIR/$tdir/$tfile
2365         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2366              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2367                 error "expected l_ost_idx: [02]$ not matched"
2368
2369         # make sure ost list has been cleared
2370         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2371         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2372                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2373         touch $DIR/$tdir/f3
2374         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2375 }
2376 run_test 27H "Set specific OSTs stripe"
2377
2378 # createtest also checks that device nodes are created and
2379 # then visible correctly (#2091)
2380 test_28() { # bug 2091
2381         test_mkdir $DIR/d28
2382         $CREATETEST $DIR/d28/ct || error "createtest failed"
2383 }
2384 run_test 28 "create/mknod/mkdir with bad file types ============"
2385
2386 test_29() {
2387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2388
2389         sync; sleep 1; sync # flush out any dirty pages from previous tests
2390         cancel_lru_locks
2391         test_mkdir $DIR/d29
2392         touch $DIR/d29/foo
2393         log 'first d29'
2394         ls -l $DIR/d29
2395
2396         declare -i LOCKCOUNTORIG=0
2397         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2398                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
2399         done
2400         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
2401
2402         declare -i LOCKUNUSEDCOUNTORIG=0
2403         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2404                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
2405         done
2406
2407         log 'second d29'
2408         ls -l $DIR/d29
2409         log 'done'
2410
2411         declare -i LOCKCOUNTCURRENT=0
2412         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2413                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
2414         done
2415
2416         declare -i LOCKUNUSEDCOUNTCURRENT=0
2417         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2418                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
2419         done
2420
2421         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
2422                 $LCTL set_param -n ldlm.dump_namespaces ""
2423                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
2424                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2425                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2426                 return 2
2427         fi
2428         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
2429                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
2430                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2431                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2432                 return 3
2433         fi
2434 }
2435 run_test 29 "IT_GETATTR regression  ============================"
2436
2437 test_30a() { # was test_30
2438         cp $(which ls) $DIR || cp /bin/ls $DIR
2439         $DIR/ls / || error "Can't execute binary from lustre"
2440         rm $DIR/ls
2441 }
2442 run_test 30a "execute binary from Lustre (execve) =============="
2443
2444 test_30b() {
2445         cp `which ls` $DIR || cp /bin/ls $DIR
2446         chmod go+rx $DIR/ls
2447         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
2448         rm $DIR/ls
2449 }
2450 run_test 30b "execute binary from Lustre as non-root ==========="
2451
2452 test_30c() { # b=22376
2453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2454
2455         cp `which ls` $DIR || cp /bin/ls $DIR
2456         chmod a-rw $DIR/ls
2457         cancel_lru_locks mdc
2458         cancel_lru_locks osc
2459         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
2460         rm -f $DIR/ls
2461 }
2462 run_test 30c "execute binary from Lustre without read perms ===="
2463
2464 test_31a() {
2465         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
2466         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
2467 }
2468 run_test 31a "open-unlink file =================================="
2469
2470 test_31b() {
2471         touch $DIR/f31 || error "touch $DIR/f31 failed"
2472         ln $DIR/f31 $DIR/f31b || error "ln failed"
2473         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
2474         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
2475 }
2476 run_test 31b "unlink file with multiple links while open ======="
2477
2478 test_31c() {
2479         touch $DIR/f31 || error "touch $DIR/f31 failed"
2480         ln $DIR/f31 $DIR/f31c || error "ln failed"
2481         multiop_bg_pause $DIR/f31 O_uc ||
2482                 error "multiop_bg_pause for $DIR/f31 failed"
2483         MULTIPID=$!
2484         $MULTIOP $DIR/f31c Ouc
2485         kill -USR1 $MULTIPID
2486         wait $MULTIPID
2487 }
2488 run_test 31c "open-unlink file with multiple links ============="
2489
2490 test_31d() {
2491         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
2492         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
2493 }
2494 run_test 31d "remove of open directory ========================="
2495
2496 test_31e() { # bug 2904
2497         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
2498 }
2499 run_test 31e "remove of open non-empty directory ==============="
2500
2501 test_31f() { # bug 4554
2502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2503
2504         set -vx
2505         test_mkdir $DIR/d31f
2506         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2507         cp /etc/hosts $DIR/d31f
2508         ls -l $DIR/d31f
2509         $LFS getstripe $DIR/d31f/hosts
2510         multiop_bg_pause $DIR/d31f D_c || return 1
2511         MULTIPID=$!
2512
2513         rm -rv $DIR/d31f || error "first of $DIR/d31f"
2514         test_mkdir $DIR/d31f
2515         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2516         cp /etc/hosts $DIR/d31f
2517         ls -l $DIR/d31f
2518         $LFS getstripe $DIR/d31f/hosts
2519         multiop_bg_pause $DIR/d31f D_c || return 1
2520         MULTIPID2=$!
2521
2522         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
2523         wait $MULTIPID || error "first opendir $MULTIPID failed"
2524
2525         sleep 6
2526
2527         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
2528         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
2529         set +vx
2530 }
2531 run_test 31f "remove of open directory with open-unlink file ==="
2532
2533 test_31g() {
2534         echo "-- cross directory link --"
2535         test_mkdir -c1 $DIR/${tdir}ga
2536         test_mkdir -c1 $DIR/${tdir}gb
2537         touch $DIR/${tdir}ga/f
2538         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
2539         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
2540         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
2541         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
2542         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
2543 }
2544 run_test 31g "cross directory link==============="
2545
2546 test_31h() {
2547         echo "-- cross directory link --"
2548         test_mkdir -c1 $DIR/${tdir}
2549         test_mkdir -c1 $DIR/${tdir}/dir
2550         touch $DIR/${tdir}/f
2551         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
2552         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
2553         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
2554         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
2555         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
2556 }
2557 run_test 31h "cross directory link under child==============="
2558
2559 test_31i() {
2560         echo "-- cross directory link --"
2561         test_mkdir -c1 $DIR/$tdir
2562         test_mkdir -c1 $DIR/$tdir/dir
2563         touch $DIR/$tdir/dir/f
2564         ln $DIR/$tdir/dir/f $DIR/$tdir/g
2565         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
2566         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
2567         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
2568         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
2569 }
2570 run_test 31i "cross directory link under parent==============="
2571
2572 test_31j() {
2573         test_mkdir -c1 -p $DIR/$tdir
2574         test_mkdir -c1 -p $DIR/$tdir/dir1
2575         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
2576         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
2577         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
2578         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
2579         return 0
2580 }
2581 run_test 31j "link for directory==============="
2582
2583 test_31k() {
2584         test_mkdir -c1 -p $DIR/$tdir
2585         touch $DIR/$tdir/s
2586         touch $DIR/$tdir/exist
2587         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
2588         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
2589         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
2590         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
2591         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
2592         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
2593         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
2594         return 0
2595 }
2596 run_test 31k "link to file: the same, non-existing, dir==============="
2597
2598 test_31m() {
2599         mkdir $DIR/d31m
2600         touch $DIR/d31m/s
2601         mkdir $DIR/d31m2
2602         touch $DIR/d31m2/exist
2603         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
2604         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
2605         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
2606         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
2607         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
2608         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
2609         return 0
2610 }
2611 run_test 31m "link to file: the same, non-existing, dir==============="
2612
2613 test_31n() {
2614         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
2615         nlink=$(stat --format=%h $DIR/$tfile)
2616         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
2617         local fd=$(free_fd)
2618         local cmd="exec $fd<$DIR/$tfile"
2619         eval $cmd
2620         cmd="exec $fd<&-"
2621         trap "eval $cmd" EXIT
2622         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
2623         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
2624         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
2625         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
2626         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
2627         eval $cmd
2628 }
2629 run_test 31n "check link count of unlinked file"
2630
2631 link_one() {
2632         local TEMPNAME=$(mktemp $1_XXXXXX)
2633         mlink $TEMPNAME $1 2> /dev/null &&
2634                 echo "$BASHPID: link $TEMPNAME to $1 succeeded"
2635         munlink $TEMPNAME
2636 }
2637
2638 test_31o() { # LU-2901
2639         test_mkdir $DIR/$tdir
2640         for LOOP in $(seq 100); do
2641                 rm -f $DIR/$tdir/$tfile*
2642                 for THREAD in $(seq 8); do
2643                         link_one $DIR/$tdir/$tfile.$LOOP &
2644                 done
2645                 wait
2646                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
2647                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
2648                         error "$LINKS duplicate links to $tfile.$LOOP" &&
2649                         break || true
2650         done
2651 }
2652 run_test 31o "duplicate hard links with same filename"
2653
2654 test_31p() {
2655         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
2656
2657         test_mkdir $DIR/$tdir
2658         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
2659         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
2660
2661         opendirunlink $DIR/$tdir/striped_dir/test1 ||
2662                 error "open unlink test1 failed"
2663         opendirunlink $DIR/$tdir/striped_dir/test2 ||
2664                 error "open unlink test2 failed"
2665
2666         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
2667                 error "test1 still exists"
2668         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
2669                 error "test2 still exists"
2670 }
2671 run_test 31p "remove of open striped directory"
2672
2673 cleanup_test32_mount() {
2674         local rc=0
2675         trap 0
2676         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
2677         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
2678         losetup -d $loopdev || true
2679         rm -rf $DIR/$tdir
2680         return $rc
2681 }
2682
2683 test_32a() {
2684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2685
2686         echo "== more mountpoints and symlinks ================="
2687         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2688         trap cleanup_test32_mount EXIT
2689         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2690         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2691                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2692         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
2693                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
2694         cleanup_test32_mount
2695 }
2696 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
2697
2698 test_32b() {
2699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2700
2701         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2702         trap cleanup_test32_mount EXIT
2703         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2704         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2705                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2706         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
2707                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
2708         cleanup_test32_mount
2709 }
2710 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
2711
2712 test_32c() {
2713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2714
2715         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2716         trap cleanup_test32_mount EXIT
2717         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2718         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2719                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2720         test_mkdir -p $DIR/$tdir/d2/test_dir
2721         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
2722                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
2723         cleanup_test32_mount
2724 }
2725 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
2726
2727 test_32d() {
2728         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2729
2730         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2731         trap cleanup_test32_mount EXIT
2732         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2733         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2734                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2735         test_mkdir -p $DIR/$tdir/d2/test_dir
2736         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
2737                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
2738         cleanup_test32_mount
2739 }
2740 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
2741
2742 test_32e() {
2743         rm -fr $DIR/$tdir
2744         test_mkdir -p $DIR/$tdir/tmp
2745         local tmp_dir=$DIR/$tdir/tmp
2746         ln -s $DIR/$tdir $tmp_dir/symlink11
2747         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
2748         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
2749         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
2750 }
2751 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
2752
2753 test_32f() {
2754         rm -fr $DIR/$tdir
2755         test_mkdir -p $DIR/$tdir/tmp
2756         local tmp_dir=$DIR/$tdir/tmp
2757         ln -s $DIR/$tdir $tmp_dir/symlink11
2758         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
2759         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
2760         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
2761 }
2762 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
2763
2764 test_32g() {
2765         local tmp_dir=$DIR/$tdir/tmp
2766         test_mkdir -p $tmp_dir
2767         test_mkdir $DIR/${tdir}2
2768         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
2769         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
2770         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
2771         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
2772         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
2773         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
2774 }
2775 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
2776
2777 test_32h() {
2778         rm -fr $DIR/$tdir $DIR/${tdir}2
2779         tmp_dir=$DIR/$tdir/tmp
2780         test_mkdir -p $tmp_dir
2781         test_mkdir $DIR/${tdir}2
2782         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
2783         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
2784         ls $tmp_dir/symlink12 || error "listing symlink12"
2785         ls $DIR/$tdir/symlink02  || error "listing symlink02"
2786 }
2787 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
2788
2789 test_32i() {
2790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2791
2792         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2793         trap cleanup_test32_mount EXIT
2794         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2795         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2796                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2797         touch $DIR/$tdir/test_file
2798         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
2799                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
2800         cleanup_test32_mount
2801 }
2802 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
2803
2804 test_32j() {
2805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2806
2807         [ -e $DIR/$tdir ] && 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         touch $DIR/$tdir/test_file
2813         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
2814                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
2815         cleanup_test32_mount
2816 }
2817 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
2818
2819 test_32k() {
2820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2821
2822         rm -fr $DIR/$tdir
2823         trap cleanup_test32_mount EXIT
2824         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2825         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2826                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2827         test_mkdir -p $DIR/$tdir/d2
2828         touch $DIR/$tdir/d2/test_file || error "touch failed"
2829         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
2830                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
2831         cleanup_test32_mount
2832 }
2833 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
2834
2835 test_32l() {
2836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2837
2838         rm -fr $DIR/$tdir
2839         trap cleanup_test32_mount EXIT
2840         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2841         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2842                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2843         test_mkdir -p $DIR/$tdir/d2
2844         touch $DIR/$tdir/d2/test_file || error "touch failed"
2845         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
2846                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
2847         cleanup_test32_mount
2848 }
2849 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
2850
2851 test_32m() {
2852         rm -fr $DIR/d32m
2853         test_mkdir -p $DIR/d32m/tmp
2854         TMP_DIR=$DIR/d32m/tmp
2855         ln -s $DIR $TMP_DIR/symlink11
2856         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
2857         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
2858                 error "symlink11 not a link"
2859         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
2860                 error "symlink01 not a link"
2861 }
2862 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
2863
2864 test_32n() {
2865         rm -fr $DIR/d32n
2866         test_mkdir -p $DIR/d32n/tmp
2867         TMP_DIR=$DIR/d32n/tmp
2868         ln -s $DIR $TMP_DIR/symlink11
2869         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
2870         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
2871         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
2872 }
2873 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
2874
2875 test_32o() {
2876         touch $DIR/$tfile
2877         test_mkdir -p $DIR/d32o/tmp
2878         TMP_DIR=$DIR/d32o/tmp
2879         ln -s $DIR/$tfile $TMP_DIR/symlink12
2880         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
2881         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
2882                 error "symlink12 not a link"
2883         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
2884         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
2885                 error "$DIR/d32o/tmp/symlink12 not file type"
2886         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
2887                 error "$DIR/d32o/symlink02 not file type"
2888 }
2889 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
2890
2891 test_32p() {
2892         log 32p_1
2893         rm -fr $DIR/d32p
2894         log 32p_2
2895         rm -f $DIR/$tfile
2896         log 32p_3
2897         touch $DIR/$tfile
2898         log 32p_4
2899         test_mkdir -p $DIR/d32p/tmp
2900         log 32p_5
2901         TMP_DIR=$DIR/d32p/tmp
2902         log 32p_6
2903         ln -s $DIR/$tfile $TMP_DIR/symlink12
2904         log 32p_7
2905         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
2906         log 32p_8
2907         cat $DIR/d32p/tmp/symlink12 ||
2908                 error "Can't open $DIR/d32p/tmp/symlink12"
2909         log 32p_9
2910         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
2911         log 32p_10
2912 }
2913 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
2914
2915 test_32q() {
2916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2917
2918         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2919         trap cleanup_test32_mount EXIT
2920         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2921         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
2922         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2923                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2924         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
2925         cleanup_test32_mount
2926 }
2927 run_test 32q "stat follows mountpoints in Lustre (should return error)"
2928
2929 test_32r() {
2930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2931
2932         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2933         trap cleanup_test32_mount EXIT
2934         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2935         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
2936         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2937                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2938         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
2939         cleanup_test32_mount
2940 }
2941 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
2942
2943 test_33aa() {
2944         rm -f $DIR/$tfile
2945         touch $DIR/$tfile
2946         chmod 444 $DIR/$tfile
2947         chown $RUNAS_ID $DIR/$tfile
2948         log 33_1
2949         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
2950         log 33_2
2951 }
2952 run_test 33aa "write file with mode 444 (should return error)"
2953
2954 test_33a() {
2955         rm -fr $DIR/$tdir
2956         test_mkdir $DIR/$tdir
2957         chown $RUNAS_ID $DIR/$tdir
2958         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
2959                 error "$RUNAS create $tdir/$tfile failed"
2960         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
2961                 error "open RDWR" || true
2962 }
2963 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
2964
2965 test_33b() {
2966         rm -fr $DIR/$tdir
2967         test_mkdir $DIR/$tdir
2968         chown $RUNAS_ID $DIR/$tdir
2969         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
2970 }
2971 run_test 33b "test open file with malformed flags (No panic)"
2972
2973 test_33c() {
2974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2975         remote_ost_nodsh && skip "remote OST with nodsh"
2976
2977         local ostnum
2978         local ostname
2979         local write_bytes
2980         local all_zeros
2981
2982         all_zeros=:
2983         rm -fr $DIR/$tdir
2984         test_mkdir $DIR/$tdir
2985         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
2986
2987         sync
2988         for ostnum in $(seq $OSTCOUNT); do
2989                 # test-framework's OST numbering is one-based, while Lustre's
2990                 # is zero-based
2991                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
2992                 # Parsing llobdstat's output sucks; we could grep the /proc
2993                 # path, but that's likely to not be as portable as using the
2994                 # llobdstat utility.  So we parse lctl output instead.
2995                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
2996                         obdfilter/$ostname/stats |
2997                         awk '/^write_bytes/ {print $7}' )
2998                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
2999                 if (( ${write_bytes:-0} > 0 ))
3000                 then
3001                         all_zeros=false
3002                         break;
3003                 fi
3004         done
3005
3006         $all_zeros || return 0
3007
3008         # Write four bytes
3009         echo foo > $DIR/$tdir/bar
3010         # Really write them
3011         sync
3012
3013         # Total up write_bytes after writing.  We'd better find non-zeros.
3014         for ostnum in $(seq $OSTCOUNT); do
3015                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3016                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3017                         obdfilter/$ostname/stats |
3018                         awk '/^write_bytes/ {print $7}' )
3019                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3020                 if (( ${write_bytes:-0} > 0 ))
3021                 then
3022                         all_zeros=false
3023                         break;
3024                 fi
3025         done
3026
3027         if $all_zeros
3028         then
3029                 for ostnum in $(seq $OSTCOUNT); do
3030                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3031                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3032                         do_facet ost$ostnum lctl get_param -n \
3033                                 obdfilter/$ostname/stats
3034                 done
3035                 error "OST not keeping write_bytes stats (b22312)"
3036         fi
3037 }
3038 run_test 33c "test llobdstat and write_bytes"
3039
3040 test_33d() {
3041         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3043
3044         local MDTIDX=1
3045         local remote_dir=$DIR/$tdir/remote_dir
3046
3047         test_mkdir $DIR/$tdir
3048         $LFS mkdir -i $MDTIDX $remote_dir ||
3049                 error "create remote directory failed"
3050
3051         touch $remote_dir/$tfile
3052         chmod 444 $remote_dir/$tfile
3053         chown $RUNAS_ID $remote_dir/$tfile
3054
3055         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3056
3057         chown $RUNAS_ID $remote_dir
3058         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3059                                         error "create" || true
3060         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3061                                     error "open RDWR" || true
3062         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3063 }
3064 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3065
3066 test_33e() {
3067         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3068
3069         mkdir $DIR/$tdir
3070
3071         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3072         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3073         mkdir $DIR/$tdir/local_dir
3074
3075         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3076         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3077         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3078
3079         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3080                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3081
3082         rmdir $DIR/$tdir/* || error "rmdir failed"
3083
3084         umask 777
3085         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3086         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3087         mkdir $DIR/$tdir/local_dir
3088
3089         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3090         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3091         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3092
3093         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3094                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3095
3096         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3097
3098         umask 000
3099         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3100         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3101         mkdir $DIR/$tdir/local_dir
3102
3103         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3104         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3105         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3106
3107         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3108                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3109 }
3110 run_test 33e "mkdir and striped directory should have same mode"
3111
3112 cleanup_33f() {
3113         trap 0
3114         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3115 }
3116
3117 test_33f() {
3118         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3119         remote_mds_nodsh && skip "remote MDS with nodsh"
3120
3121         mkdir $DIR/$tdir
3122         chmod go+rwx $DIR/$tdir
3123         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3124         trap cleanup_33f EXIT
3125
3126         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3127                 error "cannot create striped directory"
3128
3129         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3130                 error "cannot create files in striped directory"
3131
3132         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3133                 error "cannot remove files in striped directory"
3134
3135         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3136                 error "cannot remove striped directory"
3137
3138         cleanup_33f
3139 }
3140 run_test 33f "nonroot user can create, access, and remove a striped directory"
3141
3142 test_33g() {
3143         mkdir -p $DIR/$tdir/dir2
3144
3145         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3146         echo $err
3147         [[ $err =~ "exists" ]] || error "Not exists error"
3148 }
3149 run_test 33g "nonroot user create already existing root created file"
3150
3151 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3152 test_34a() {
3153         rm -f $DIR/f34
3154         $MCREATE $DIR/f34 || error "mcreate failed"
3155         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3156                 error "getstripe failed"
3157         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3158         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3159                 error "getstripe failed"
3160         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3161                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3162 }
3163 run_test 34a "truncate file that has not been opened ==========="
3164
3165 test_34b() {
3166         [ ! -f $DIR/f34 ] && test_34a
3167         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3168                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3169         $OPENFILE -f O_RDONLY $DIR/f34
3170         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3171                 error "getstripe failed"
3172         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3173                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3174 }
3175 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3176
3177 test_34c() {
3178         [ ! -f $DIR/f34 ] && test_34a
3179         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3180                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3181         $OPENFILE -f O_RDWR $DIR/f34
3182         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3183                 error "$LFS getstripe failed"
3184         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3185                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3186 }
3187 run_test 34c "O_RDWR opening file-with-size works =============="
3188
3189 test_34d() {
3190         [ ! -f $DIR/f34 ] && test_34a
3191         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3192                 error "dd failed"
3193         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3194                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3195         rm $DIR/f34
3196 }
3197 run_test 34d "write to sparse file ============================="
3198
3199 test_34e() {
3200         rm -f $DIR/f34e
3201         $MCREATE $DIR/f34e || error "mcreate failed"
3202         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3203         $CHECKSTAT -s 1000 $DIR/f34e ||
3204                 error "Size of $DIR/f34e not equal to 1000 bytes"
3205         $OPENFILE -f O_RDWR $DIR/f34e
3206         $CHECKSTAT -s 1000 $DIR/f34e ||
3207                 error "Size of $DIR/f34e not equal to 1000 bytes"
3208 }
3209 run_test 34e "create objects, some with size and some without =="
3210
3211 test_34f() { # bug 6242, 6243
3212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3213
3214         SIZE34F=48000
3215         rm -f $DIR/f34f
3216         $MCREATE $DIR/f34f || error "mcreate failed"
3217         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3218         dd if=$DIR/f34f of=$TMP/f34f
3219         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3220         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3221         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3222         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3223         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3224 }
3225 run_test 34f "read from a file with no objects until EOF ======="
3226
3227 test_34g() {
3228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3229
3230         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3231                 error "dd failed"
3232         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3233         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3234                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3235         cancel_lru_locks osc
3236         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3237                 error "wrong size after lock cancel"
3238
3239         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3240         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3241                 error "expanding truncate failed"
3242         cancel_lru_locks osc
3243         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3244                 error "wrong expanded size after lock cancel"
3245 }
3246 run_test 34g "truncate long file ==============================="
3247
3248 test_34h() {
3249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3250
3251         local gid=10
3252         local sz=1000
3253
3254         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3255         sync # Flush the cache so that multiop below does not block on cache
3256              # flush when getting the group lock
3257         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3258         MULTIPID=$!
3259
3260         # Since just timed wait is not good enough, let's do a sync write
3261         # that way we are sure enough time for a roundtrip + processing
3262         # passed + 2 seconds of extra margin.
3263         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3264         rm $DIR/${tfile}-1
3265         sleep 2
3266
3267         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3268                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3269                 kill -9 $MULTIPID
3270         fi
3271         wait $MULTIPID
3272         local nsz=`stat -c %s $DIR/$tfile`
3273         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3274 }
3275 run_test 34h "ftruncate file under grouplock should not block"
3276
3277 test_35a() {
3278         cp /bin/sh $DIR/f35a
3279         chmod 444 $DIR/f35a
3280         chown $RUNAS_ID $DIR/f35a
3281         $RUNAS $DIR/f35a && error || true
3282         rm $DIR/f35a
3283 }
3284 run_test 35a "exec file with mode 444 (should return and not leak)"
3285
3286 test_36a() {
3287         rm -f $DIR/f36
3288         utime $DIR/f36 || error "utime failed for MDS"
3289 }
3290 run_test 36a "MDS utime check (mknod, utime)"
3291
3292 test_36b() {
3293         echo "" > $DIR/f36
3294         utime $DIR/f36 || error "utime failed for OST"
3295 }
3296 run_test 36b "OST utime check (open, utime)"
3297
3298 test_36c() {
3299         rm -f $DIR/d36/f36
3300         test_mkdir $DIR/d36
3301         chown $RUNAS_ID $DIR/d36
3302         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3303 }
3304 run_test 36c "non-root MDS utime check (mknod, utime)"
3305
3306 test_36d() {
3307         [ ! -d $DIR/d36 ] && test_36c
3308         echo "" > $DIR/d36/f36
3309         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3310 }
3311 run_test 36d "non-root OST utime check (open, utime)"
3312
3313 test_36e() {
3314         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3315
3316         test_mkdir $DIR/$tdir
3317         touch $DIR/$tdir/$tfile
3318         $RUNAS utime $DIR/$tdir/$tfile &&
3319                 error "utime worked, expected failure" || true
3320 }
3321 run_test 36e "utime on non-owned file (should return error)"
3322
3323 subr_36fh() {
3324         local fl="$1"
3325         local LANG_SAVE=$LANG
3326         local LC_LANG_SAVE=$LC_LANG
3327         export LANG=C LC_LANG=C # for date language
3328
3329         DATESTR="Dec 20  2000"
3330         test_mkdir $DIR/$tdir
3331         lctl set_param fail_loc=$fl
3332         date; date +%s
3333         cp /etc/hosts $DIR/$tdir/$tfile
3334         sync & # write RPC generated with "current" inode timestamp, but delayed
3335         sleep 1
3336         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3337         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3338         cancel_lru_locks $OSC
3339         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3340         date; date +%s
3341         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3342                 echo "BEFORE: $LS_BEFORE" && \
3343                 echo "AFTER : $LS_AFTER" && \
3344                 echo "WANT  : $DATESTR" && \
3345                 error "$DIR/$tdir/$tfile timestamps changed" || true
3346
3347         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3348 }
3349
3350 test_36f() {
3351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3352
3353         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3354         subr_36fh "0x80000214"
3355 }
3356 run_test 36f "utime on file racing with OST BRW write =========="
3357
3358 test_36g() {
3359         remote_ost_nodsh && skip "remote OST with nodsh"
3360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3361         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
3362                 skip "Need MDS version at least 2.12.51"
3363
3364         local fmd_max_age
3365         local fmd
3366         local facet="ost1"
3367         local tgt="obdfilter"
3368
3369         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
3370
3371         test_mkdir $DIR/$tdir
3372         fmd_max_age=$(do_facet $facet \
3373                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
3374                 head -n 1")
3375
3376         echo "FMD max age: ${fmd_max_age}s"
3377         touch $DIR/$tdir/$tfile
3378         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3379                 gawk '{cnt=cnt+$1}  END{print cnt}')
3380         echo "FMD before: $fmd"
3381         [[ $fmd == 0 ]] &&
3382                 error "FMD wasn't create by touch"
3383         sleep $((fmd_max_age + 12))
3384         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3385                 gawk '{cnt=cnt+$1}  END{print cnt}')
3386         echo "FMD after: $fmd"
3387         [[ $fmd == 0 ]] ||
3388                 error "FMD wasn't expired by ping"
3389 }
3390 run_test 36g "FMD cache expiry ====================="
3391
3392 test_36h() {
3393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3394
3395         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
3396         subr_36fh "0x80000227"
3397 }
3398 run_test 36h "utime on file racing with OST BRW write =========="
3399
3400 test_36i() {
3401         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3402
3403         test_mkdir $DIR/$tdir
3404         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
3405
3406         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
3407         local new_mtime=$((mtime + 200))
3408
3409         #change Modify time of striped dir
3410         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
3411                         error "change mtime failed"
3412
3413         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
3414
3415         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
3416 }
3417 run_test 36i "change mtime on striped directory"
3418
3419 # test_37 - duplicate with tests 32q 32r
3420
3421 test_38() {
3422         local file=$DIR/$tfile
3423         touch $file
3424         openfile -f O_DIRECTORY $file
3425         local RC=$?
3426         local ENOTDIR=20
3427         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
3428         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
3429 }
3430 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
3431
3432 test_39a() { # was test_39
3433         touch $DIR/$tfile
3434         touch $DIR/${tfile}2
3435 #       ls -l  $DIR/$tfile $DIR/${tfile}2
3436 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
3437 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
3438         sleep 2
3439         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
3440         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
3441                 echo "mtime"
3442                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
3443                 echo "atime"
3444                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
3445                 echo "ctime"
3446                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
3447                 error "O_TRUNC didn't change timestamps"
3448         fi
3449 }
3450 run_test 39a "mtime changed on create"
3451
3452 test_39b() {
3453         test_mkdir -c1 $DIR/$tdir
3454         cp -p /etc/passwd $DIR/$tdir/fopen
3455         cp -p /etc/passwd $DIR/$tdir/flink
3456         cp -p /etc/passwd $DIR/$tdir/funlink
3457         cp -p /etc/passwd $DIR/$tdir/frename
3458         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
3459
3460         sleep 1
3461         echo "aaaaaa" >> $DIR/$tdir/fopen
3462         echo "aaaaaa" >> $DIR/$tdir/flink
3463         echo "aaaaaa" >> $DIR/$tdir/funlink
3464         echo "aaaaaa" >> $DIR/$tdir/frename
3465
3466         local open_new=`stat -c %Y $DIR/$tdir/fopen`
3467         local link_new=`stat -c %Y $DIR/$tdir/flink`
3468         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
3469         local rename_new=`stat -c %Y $DIR/$tdir/frename`
3470
3471         cat $DIR/$tdir/fopen > /dev/null
3472         ln $DIR/$tdir/flink $DIR/$tdir/flink2
3473         rm -f $DIR/$tdir/funlink2
3474         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
3475
3476         for (( i=0; i < 2; i++ )) ; do
3477                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
3478                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
3479                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
3480                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
3481
3482                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
3483                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
3484                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
3485                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
3486
3487                 cancel_lru_locks $OSC
3488                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3489         done
3490 }
3491 run_test 39b "mtime change on open, link, unlink, rename  ======"
3492
3493 # this should be set to past
3494 TEST_39_MTIME=`date -d "1 year ago" +%s`
3495
3496 # bug 11063
3497 test_39c() {
3498         touch $DIR1/$tfile
3499         sleep 2
3500         local mtime0=`stat -c %Y $DIR1/$tfile`
3501
3502         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3503         local mtime1=`stat -c %Y $DIR1/$tfile`
3504         [ "$mtime1" = $TEST_39_MTIME ] || \
3505                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
3506
3507         local d1=`date +%s`
3508         echo hello >> $DIR1/$tfile
3509         local d2=`date +%s`
3510         local mtime2=`stat -c %Y $DIR1/$tfile`
3511         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
3512                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
3513
3514         mv $DIR1/$tfile $DIR1/$tfile-1
3515
3516         for (( i=0; i < 2; i++ )) ; do
3517                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
3518                 [ "$mtime2" = "$mtime3" ] || \
3519                         error "mtime ($mtime2) changed (to $mtime3) on rename"
3520
3521                 cancel_lru_locks $OSC
3522                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3523         done
3524 }
3525 run_test 39c "mtime change on rename ==========================="
3526
3527 # bug 21114
3528 test_39d() {
3529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3530
3531         touch $DIR1/$tfile
3532         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3533
3534         for (( i=0; i < 2; i++ )) ; do
3535                 local mtime=`stat -c %Y $DIR1/$tfile`
3536                 [ $mtime = $TEST_39_MTIME ] || \
3537                         error "mtime($mtime) is not set to $TEST_39_MTIME"
3538
3539                 cancel_lru_locks $OSC
3540                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3541         done
3542 }
3543 run_test 39d "create, utime, stat =============================="
3544
3545 # bug 21114
3546 test_39e() {
3547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3548
3549         touch $DIR1/$tfile
3550         local mtime1=`stat -c %Y $DIR1/$tfile`
3551
3552         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3553
3554         for (( i=0; i < 2; i++ )) ; do
3555                 local mtime2=`stat -c %Y $DIR1/$tfile`
3556                 [ $mtime2 = $TEST_39_MTIME ] || \
3557                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
3558
3559                 cancel_lru_locks $OSC
3560                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3561         done
3562 }
3563 run_test 39e "create, stat, utime, stat ========================"
3564
3565 # bug 21114
3566 test_39f() {
3567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3568
3569         touch $DIR1/$tfile
3570         mtime1=`stat -c %Y $DIR1/$tfile`
3571
3572         sleep 2
3573         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3574
3575         for (( i=0; i < 2; i++ )) ; do
3576                 local mtime2=`stat -c %Y $DIR1/$tfile`
3577                 [ $mtime2 = $TEST_39_MTIME ] || \
3578                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
3579
3580                 cancel_lru_locks $OSC
3581                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3582         done
3583 }
3584 run_test 39f "create, stat, sleep, utime, stat ================="
3585
3586 # bug 11063
3587 test_39g() {
3588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3589
3590         echo hello >> $DIR1/$tfile
3591         local mtime1=`stat -c %Y $DIR1/$tfile`
3592
3593         sleep 2
3594         chmod o+r $DIR1/$tfile
3595
3596         for (( i=0; i < 2; i++ )) ; do
3597                 local mtime2=`stat -c %Y $DIR1/$tfile`
3598                 [ "$mtime1" = "$mtime2" ] || \
3599                         error "lost mtime: $mtime2, should be $mtime1"
3600
3601                 cancel_lru_locks $OSC
3602                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3603         done
3604 }
3605 run_test 39g "write, chmod, stat ==============================="
3606
3607 # bug 11063
3608 test_39h() {
3609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3610
3611         touch $DIR1/$tfile
3612         sleep 1
3613
3614         local d1=`date`
3615         echo hello >> $DIR1/$tfile
3616         local mtime1=`stat -c %Y $DIR1/$tfile`
3617
3618         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3619         local d2=`date`
3620         if [ "$d1" != "$d2" ]; then
3621                 echo "write and touch not within one second"
3622         else
3623                 for (( i=0; i < 2; i++ )) ; do
3624                         local mtime2=`stat -c %Y $DIR1/$tfile`
3625                         [ "$mtime2" = $TEST_39_MTIME ] || \
3626                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
3627
3628                         cancel_lru_locks $OSC
3629                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3630                 done
3631         fi
3632 }
3633 run_test 39h "write, utime within one second, stat ============="
3634
3635 test_39i() {
3636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3637
3638         touch $DIR1/$tfile
3639         sleep 1
3640
3641         echo hello >> $DIR1/$tfile
3642         local mtime1=`stat -c %Y $DIR1/$tfile`
3643
3644         mv $DIR1/$tfile $DIR1/$tfile-1
3645
3646         for (( i=0; i < 2; i++ )) ; do
3647                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
3648
3649                 [ "$mtime1" = "$mtime2" ] || \
3650                         error "lost mtime: $mtime2, should be $mtime1"
3651
3652                 cancel_lru_locks $OSC
3653                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3654         done
3655 }
3656 run_test 39i "write, rename, stat =============================="
3657
3658 test_39j() {
3659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3660
3661         start_full_debug_logging
3662         touch $DIR1/$tfile
3663         sleep 1
3664
3665         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
3666         lctl set_param fail_loc=0x80000412
3667         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
3668                 error "multiop failed"
3669         local multipid=$!
3670         local mtime1=`stat -c %Y $DIR1/$tfile`
3671
3672         mv $DIR1/$tfile $DIR1/$tfile-1
3673
3674         kill -USR1 $multipid
3675         wait $multipid || error "multiop close failed"
3676
3677         for (( i=0; i < 2; i++ )) ; do
3678                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
3679                 [ "$mtime1" = "$mtime2" ] ||
3680                         error "mtime is lost on close: $mtime2, " \
3681                               "should be $mtime1"
3682
3683                 cancel_lru_locks $OSC
3684                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3685         done
3686         lctl set_param fail_loc=0
3687         stop_full_debug_logging
3688 }
3689 run_test 39j "write, rename, close, stat ======================="
3690
3691 test_39k() {
3692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3693
3694         touch $DIR1/$tfile
3695         sleep 1
3696
3697         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
3698         local multipid=$!
3699         local mtime1=`stat -c %Y $DIR1/$tfile`
3700
3701         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3702
3703         kill -USR1 $multipid
3704         wait $multipid || error "multiop close failed"
3705
3706         for (( i=0; i < 2; i++ )) ; do
3707                 local mtime2=`stat -c %Y $DIR1/$tfile`
3708
3709                 [ "$mtime2" = $TEST_39_MTIME ] || \
3710                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
3711
3712                 cancel_lru_locks osc
3713                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3714         done
3715 }
3716 run_test 39k "write, utime, close, stat ========================"
3717
3718 # this should be set to future
3719 TEST_39_ATIME=`date -d "1 year" +%s`
3720
3721 test_39l() {
3722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3723         remote_mds_nodsh && skip "remote MDS with nodsh"
3724
3725         local atime_diff=$(do_facet $SINGLEMDS \
3726                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
3727         rm -rf $DIR/$tdir
3728         mkdir -p $DIR/$tdir
3729
3730         # test setting directory atime to future
3731         touch -a -d @$TEST_39_ATIME $DIR/$tdir
3732         local atime=$(stat -c %X $DIR/$tdir)
3733         [ "$atime" = $TEST_39_ATIME ] ||
3734                 error "atime is not set to future: $atime, $TEST_39_ATIME"
3735
3736         # test setting directory atime from future to now
3737         local now=$(date +%s)
3738         touch -a -d @$now $DIR/$tdir
3739
3740         atime=$(stat -c %X $DIR/$tdir)
3741         [ "$atime" -eq "$now"  ] ||
3742                 error "atime is not updated from future: $atime, $now"
3743
3744         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
3745         sleep 3
3746
3747         # test setting directory atime when now > dir atime + atime_diff
3748         local d1=$(date +%s)
3749         ls $DIR/$tdir
3750         local d2=$(date +%s)
3751         cancel_lru_locks mdc
3752         atime=$(stat -c %X $DIR/$tdir)
3753         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
3754                 error "atime is not updated  : $atime, should be $d2"
3755
3756         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
3757         sleep 3
3758
3759         # test not setting directory atime when now < dir atime + atime_diff
3760         ls $DIR/$tdir
3761         cancel_lru_locks mdc
3762         atime=$(stat -c %X $DIR/$tdir)
3763         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
3764                 error "atime is updated to $atime, should remain $d1<atime<$d2"
3765
3766         do_facet $SINGLEMDS \
3767                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
3768 }
3769 run_test 39l "directory atime update ==========================="
3770
3771 test_39m() {
3772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3773
3774         touch $DIR1/$tfile
3775         sleep 2
3776         local far_past_mtime=$(date -d "May 29 1953" +%s)
3777         local far_past_atime=$(date -d "Dec 17 1903" +%s)
3778
3779         touch -m -d @$far_past_mtime $DIR1/$tfile
3780         touch -a -d @$far_past_atime $DIR1/$tfile
3781
3782         for (( i=0; i < 2; i++ )) ; do
3783                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
3784                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
3785                         error "atime or mtime set incorrectly"
3786
3787                 cancel_lru_locks $OSC
3788                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3789         done
3790 }
3791 run_test 39m "test atime and mtime before 1970"
3792
3793 test_39n() { # LU-3832
3794         remote_mds_nodsh && skip "remote MDS with nodsh"
3795
3796         local atime_diff=$(do_facet $SINGLEMDS \
3797                 lctl get_param -n mdd.*MDT0000*.atime_diff)
3798         local atime0
3799         local atime1
3800         local atime2
3801
3802         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
3803
3804         rm -rf $DIR/$tfile
3805         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
3806         atime0=$(stat -c %X $DIR/$tfile)
3807
3808         sleep 5
3809         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
3810         atime1=$(stat -c %X $DIR/$tfile)
3811
3812         sleep 5
3813         cancel_lru_locks mdc
3814         cancel_lru_locks osc
3815         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
3816         atime2=$(stat -c %X $DIR/$tfile)
3817
3818         do_facet $SINGLEMDS \
3819                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
3820
3821         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
3822         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
3823 }
3824 run_test 39n "check that O_NOATIME is honored"
3825
3826 test_39o() {
3827         TESTDIR=$DIR/$tdir/$tfile
3828         [ -e $TESTDIR ] && rm -rf $TESTDIR
3829         mkdir -p $TESTDIR
3830         cd $TESTDIR
3831         links1=2
3832         ls
3833         mkdir a b
3834         ls
3835         links2=$(stat -c %h .)
3836         [ $(($links1 + 2)) != $links2 ] &&
3837                 error "wrong links count $(($links1 + 2)) != $links2"
3838         rmdir b
3839         links3=$(stat -c %h .)
3840         [ $(($links1 + 1)) != $links3 ] &&
3841                 error "wrong links count $links1 != $links3"
3842         return 0
3843 }
3844 run_test 39o "directory cached attributes updated after create"
3845
3846 test_39p() {
3847         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3848
3849         local MDTIDX=1
3850         TESTDIR=$DIR/$tdir/$tdir
3851         [ -e $TESTDIR ] && rm -rf $TESTDIR
3852         test_mkdir -p $TESTDIR
3853         cd $TESTDIR
3854         links1=2
3855         ls
3856         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
3857         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
3858         ls
3859         links2=$(stat -c %h .)
3860         [ $(($links1 + 2)) != $links2 ] &&
3861                 error "wrong links count $(($links1 + 2)) != $links2"
3862         rmdir remote_dir2
3863         links3=$(stat -c %h .)
3864         [ $(($links1 + 1)) != $links3 ] &&
3865                 error "wrong links count $links1 != $links3"
3866         return 0
3867 }
3868 run_test 39p "remote directory cached attributes updated after create ========"
3869
3870
3871 test_39q() { # LU-8041
3872         local testdir=$DIR/$tdir
3873         mkdir -p $testdir
3874         multiop_bg_pause $testdir D_c || error "multiop failed"
3875         local multipid=$!
3876         cancel_lru_locks mdc
3877         kill -USR1 $multipid
3878         local atime=$(stat -c %X $testdir)
3879         [ "$atime" -ne 0 ] || error "atime is zero"
3880 }
3881 run_test 39q "close won't zero out atime"
3882
3883 test_40() {
3884         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
3885         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
3886                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
3887         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
3888                 error "$tfile is not 4096 bytes in size"
3889 }
3890 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
3891
3892 test_41() {
3893         # bug 1553
3894         small_write $DIR/f41 18
3895 }
3896 run_test 41 "test small file write + fstat ====================="
3897
3898 count_ost_writes() {
3899         lctl get_param -n ${OSC}.*.stats |
3900                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
3901                         END { printf("%0.0f", writes) }'
3902 }
3903
3904 # decent default
3905 WRITEBACK_SAVE=500
3906 DIRTY_RATIO_SAVE=40
3907 MAX_DIRTY_RATIO=50
3908 BG_DIRTY_RATIO_SAVE=10
3909 MAX_BG_DIRTY_RATIO=25
3910
3911 start_writeback() {
3912         trap 0
3913         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
3914         # dirty_ratio, dirty_background_ratio
3915         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
3916                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
3917                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
3918                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
3919         else
3920                 # if file not here, we are a 2.4 kernel
3921                 kill -CONT `pidof kupdated`
3922         fi
3923 }
3924
3925 stop_writeback() {
3926         # setup the trap first, so someone cannot exit the test at the
3927         # exact wrong time and mess up a machine
3928         trap start_writeback EXIT
3929         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
3930         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
3931                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
3932                 sysctl -w vm.dirty_writeback_centisecs=0
3933                 sysctl -w vm.dirty_writeback_centisecs=0
3934                 # save and increase /proc/sys/vm/dirty_ratio
3935                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
3936                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
3937                 # save and increase /proc/sys/vm/dirty_background_ratio
3938                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
3939                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
3940         else
3941                 # if file not here, we are a 2.4 kernel
3942                 kill -STOP `pidof kupdated`
3943         fi
3944 }
3945
3946 # ensure that all stripes have some grant before we test client-side cache
3947 setup_test42() {
3948         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
3949                 dd if=/dev/zero of=$i bs=4k count=1
3950                 rm $i
3951         done
3952 }
3953
3954 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
3955 # file truncation, and file removal.
3956 test_42a() {
3957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3958
3959         setup_test42
3960         cancel_lru_locks $OSC
3961         stop_writeback
3962         sync; sleep 1; sync # just to be safe
3963         BEFOREWRITES=`count_ost_writes`
3964         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
3965         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
3966         AFTERWRITES=`count_ost_writes`
3967         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
3968                 error "$BEFOREWRITES < $AFTERWRITES"
3969         start_writeback
3970 }
3971 run_test 42a "ensure that we don't flush on close"
3972
3973 test_42b() {
3974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3975
3976         setup_test42
3977         cancel_lru_locks $OSC
3978         stop_writeback
3979         sync
3980         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
3981         BEFOREWRITES=$(count_ost_writes)
3982         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
3983         AFTERWRITES=$(count_ost_writes)
3984         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
3985                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
3986         fi
3987         BEFOREWRITES=$(count_ost_writes)
3988         sync || error "sync: $?"
3989         AFTERWRITES=$(count_ost_writes)
3990         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
3991                 error "$BEFOREWRITES < $AFTERWRITES on sync"
3992         fi
3993         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
3994         start_writeback
3995         return 0
3996 }
3997 run_test 42b "test destroy of file with cached dirty data ======"
3998
3999 # if these tests just want to test the effect of truncation,
4000 # they have to be very careful.  consider:
4001 # - the first open gets a {0,EOF}PR lock
4002 # - the first write conflicts and gets a {0, count-1}PW
4003 # - the rest of the writes are under {count,EOF}PW
4004 # - the open for truncate tries to match a {0,EOF}PR
4005 #   for the filesize and cancels the PWs.
4006 # any number of fixes (don't get {0,EOF} on open, match
4007 # composite locks, do smarter file size management) fix
4008 # this, but for now we want these tests to verify that
4009 # the cancellation with truncate intent works, so we
4010 # start the file with a full-file pw lock to match against
4011 # until the truncate.
4012 trunc_test() {
4013         test=$1
4014         file=$DIR/$test
4015         offset=$2
4016         cancel_lru_locks $OSC
4017         stop_writeback
4018         # prime the file with 0,EOF PW to match
4019         touch $file
4020         $TRUNCATE $file 0
4021         sync; sync
4022         # now the real test..
4023         dd if=/dev/zero of=$file bs=1024 count=100
4024         BEFOREWRITES=`count_ost_writes`
4025         $TRUNCATE $file $offset
4026         cancel_lru_locks $OSC
4027         AFTERWRITES=`count_ost_writes`
4028         start_writeback
4029 }
4030
4031 test_42c() {
4032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4033
4034         trunc_test 42c 1024
4035         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4036                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4037         rm $file
4038 }
4039 run_test 42c "test partial truncate of file with cached dirty data"
4040
4041 test_42d() {
4042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4043
4044         trunc_test 42d 0
4045         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4046                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4047         rm $file
4048 }
4049 run_test 42d "test complete truncate of file with cached dirty data"
4050
4051 test_42e() { # bug22074
4052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4053
4054         local TDIR=$DIR/${tdir}e
4055         local pages=16 # hardcoded 16 pages, don't change it.
4056         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4057         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4058         local max_dirty_mb
4059         local warmup_files
4060
4061         test_mkdir $DIR/${tdir}e
4062         $LFS setstripe -c 1 $TDIR
4063         createmany -o $TDIR/f $files
4064
4065         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4066
4067         # we assume that with $OSTCOUNT files, at least one of them will
4068         # be allocated on OST0.
4069         warmup_files=$((OSTCOUNT * max_dirty_mb))
4070         createmany -o $TDIR/w $warmup_files
4071
4072         # write a large amount of data into one file and sync, to get good
4073         # avail_grant number from OST.
4074         for ((i=0; i<$warmup_files; i++)); do
4075                 idx=$($LFS getstripe -i $TDIR/w$i)
4076                 [ $idx -ne 0 ] && continue
4077                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4078                 break
4079         done
4080         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4081         sync
4082         $LCTL get_param $proc_osc0/cur_dirty_bytes
4083         $LCTL get_param $proc_osc0/cur_grant_bytes
4084
4085         # create as much dirty pages as we can while not to trigger the actual
4086         # RPCs directly. but depends on the env, VFS may trigger flush during this
4087         # period, hopefully we are good.
4088         for ((i=0; i<$warmup_files; i++)); do
4089                 idx=$($LFS getstripe -i $TDIR/w$i)
4090                 [ $idx -ne 0 ] && continue
4091                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4092         done
4093         $LCTL get_param $proc_osc0/cur_dirty_bytes
4094         $LCTL get_param $proc_osc0/cur_grant_bytes
4095
4096         # perform the real test
4097         $LCTL set_param $proc_osc0/rpc_stats 0
4098         for ((;i<$files; i++)); do
4099                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4100                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4101         done
4102         sync
4103         $LCTL get_param $proc_osc0/rpc_stats
4104
4105         local percent=0
4106         local have_ppr=false
4107         $LCTL get_param $proc_osc0/rpc_stats |
4108                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4109                         # skip lines until we are at the RPC histogram data
4110                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4111                         $have_ppr || continue
4112
4113                         # we only want the percent stat for < 16 pages
4114                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4115
4116                         percent=$((percent + WPCT))
4117                         if [[ $percent -gt 15 ]]; then
4118                                 error "less than 16-pages write RPCs" \
4119                                       "$percent% > 15%"
4120                                 break
4121                         fi
4122                 done
4123         rm -rf $TDIR
4124 }
4125 run_test 42e "verify sub-RPC writes are not done synchronously"
4126
4127 test_43A() { # was test_43
4128         test_mkdir $DIR/$tdir
4129         cp -p /bin/ls $DIR/$tdir/$tfile
4130         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4131         pid=$!
4132         # give multiop a chance to open
4133         sleep 1
4134
4135         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4136         kill -USR1 $pid
4137 }
4138 run_test 43A "execution of file opened for write should return -ETXTBSY"
4139
4140 test_43a() {
4141         test_mkdir $DIR/$tdir
4142         cp -p $(which $MULTIOP) $DIR/$tdir/multiop ||
4143                 cp -p multiop $DIR/$tdir/multiop
4144         MULTIOP_PROG=$DIR/$tdir/multiop multiop_bg_pause $TMP/$tfile.junk O_c ||
4145                 error "multiop open $TMP/$tfile.junk failed"
4146         rm $TMP/$tfile.junk     # delete junk file on close (not part of test)
4147         MULTIOP_PID=$!
4148         $MULTIOP $DIR/$tdir/multiop Oc && error "expected error, got success"
4149         kill -USR1 $MULTIOP_PID || error "kill -USR1 PID $MULTIOP_PID failed"
4150         wait $MULTIOP_PID || error "wait PID $MULTIOP_PID failed"
4151 }
4152 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4153
4154 test_43b() {
4155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4156
4157         test_mkdir $DIR/$tdir
4158         cp -p $(which $MULTIOP) $DIR/$tdir/multiop ||
4159                 cp -p multiop $DIR/$tdir/multiop
4160         MULTIOP_PROG=$DIR/$tdir/multiop multiop_bg_pause $TMP/$tfile.junk O_c ||
4161                 error "multiop open $TMP/$tfile.junk failed"
4162         rm $TMP/$tfile.junk     # delete junk file on close (not part of test)
4163         MULTIOP_PID=$!
4164         $TRUNCATE $DIR/$tdir/multiop 0 && error "expected error, got success"
4165         kill -USR1 $MULTIOP_PID || error "kill -USR1 PID $MULTIOP_PID failed"
4166         wait $MULTIOP_PID || error "wait PID $MULTIOP_PID failed"
4167 }
4168 run_test 43b "truncate of file being executed should return -ETXTBSY"
4169
4170 test_43c() {
4171         local testdir="$DIR/$tdir"
4172         test_mkdir $testdir
4173         cp $SHELL $testdir/
4174         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4175                 ( cd $testdir && md5sum -c )
4176 }
4177 run_test 43c "md5sum of copy into lustre"
4178
4179 test_44A() { # was test_44
4180         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4181
4182         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4183         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4184 }
4185 run_test 44A "zero length read from a sparse stripe"
4186
4187 test_44a() {
4188         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4189                 awk '{ print $2 }')
4190         [ -z "$nstripe" ] && skip "can't get stripe info"
4191         [[ $nstripe -gt $OSTCOUNT ]] &&
4192                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4193
4194         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4195                 awk '{ print $2 }')
4196         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4197                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4198                         awk '{ print $2 }')
4199         fi
4200
4201         OFFSETS="0 $((stride/2)) $((stride-1))"
4202         for offset in $OFFSETS; do
4203                 for i in $(seq 0 $((nstripe-1))); do
4204                         local GLOBALOFFSETS=""
4205                         # size in Bytes
4206                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4207                         local myfn=$DIR/d44a-$size
4208                         echo "--------writing $myfn at $size"
4209                         ll_sparseness_write $myfn $size ||
4210                                 error "ll_sparseness_write"
4211                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4212                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4213                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4214
4215                         for j in $(seq 0 $((nstripe-1))); do
4216                                 # size in Bytes
4217                                 size=$((((j + $nstripe )*$stride + $offset)))
4218                                 ll_sparseness_write $myfn $size ||
4219                                         error "ll_sparseness_write"
4220                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4221                         done
4222                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4223                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4224                         rm -f $myfn
4225                 done
4226         done
4227 }
4228 run_test 44a "test sparse pwrite ==============================="
4229
4230 dirty_osc_total() {
4231         tot=0
4232         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4233                 tot=$(($tot + $d))
4234         done
4235         echo $tot
4236 }
4237 do_dirty_record() {
4238         before=`dirty_osc_total`
4239         echo executing "\"$*\""
4240         eval $*
4241         after=`dirty_osc_total`
4242         echo before $before, after $after
4243 }
4244 test_45() {
4245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4246
4247         f="$DIR/f45"
4248         # Obtain grants from OST if it supports it
4249         echo blah > ${f}_grant
4250         stop_writeback
4251         sync
4252         do_dirty_record "echo blah > $f"
4253         [[ $before -eq $after ]] && error "write wasn't cached"
4254         do_dirty_record "> $f"
4255         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4256         do_dirty_record "echo blah > $f"
4257         [[ $before -eq $after ]] && error "write wasn't cached"
4258         do_dirty_record "sync"
4259         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4260         do_dirty_record "echo blah > $f"
4261         [[ $before -eq $after ]] && error "write wasn't cached"
4262         do_dirty_record "cancel_lru_locks osc"
4263         [[ $before -gt $after ]] ||
4264                 error "lock cancellation didn't lower dirty count"
4265         start_writeback
4266 }
4267 run_test 45 "osc io page accounting ============================"
4268
4269 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4270 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4271 # objects offset and an assert hit when an rpc was built with 1023's mapped
4272 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4273 test_46() {
4274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4275
4276         f="$DIR/f46"
4277         stop_writeback
4278         sync
4279         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4280         sync
4281         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4282         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4283         sync
4284         start_writeback
4285 }
4286 run_test 46 "dirtying a previously written page ================"
4287
4288 # test_47 is removed "Device nodes check" is moved to test_28
4289
4290 test_48a() { # bug 2399
4291         [ "$mds1_FSTYPE" = "zfs" ] &&
4292         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4293                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4294
4295         test_mkdir $DIR/$tdir
4296         cd $DIR/$tdir
4297         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4298         test_mkdir $DIR/$tdir
4299         touch foo || error "'touch foo' failed after recreating cwd"
4300         test_mkdir bar
4301         touch .foo || error "'touch .foo' failed after recreating cwd"
4302         test_mkdir .bar
4303         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4304         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4305         cd . || error "'cd .' failed after recreating cwd"
4306         mkdir . && error "'mkdir .' worked after recreating cwd"
4307         rmdir . && error "'rmdir .' worked after recreating cwd"
4308         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4309         cd .. || error "'cd ..' failed after recreating cwd"
4310 }
4311 run_test 48a "Access renamed working dir (should return errors)="
4312
4313 test_48b() { # bug 2399
4314         rm -rf $DIR/$tdir
4315         test_mkdir $DIR/$tdir
4316         cd $DIR/$tdir
4317         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4318         touch foo && error "'touch foo' worked after removing cwd"
4319         mkdir foo && error "'mkdir foo' worked after removing cwd"
4320         touch .foo && error "'touch .foo' worked after removing cwd"
4321         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
4322         ls . > /dev/null && error "'ls .' worked after removing cwd"
4323         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4324         mkdir . && error "'mkdir .' worked after removing cwd"
4325         rmdir . && error "'rmdir .' worked after removing cwd"
4326         ln -s . foo && error "'ln -s .' worked after removing cwd"
4327         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
4328 }
4329 run_test 48b "Access removed working dir (should return errors)="
4330
4331 test_48c() { # bug 2350
4332         #lctl set_param debug=-1
4333         #set -vx
4334         rm -rf $DIR/$tdir
4335         test_mkdir -p $DIR/$tdir/dir
4336         cd $DIR/$tdir/dir
4337         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4338         $TRACE touch foo && error "touch foo worked after removing cwd"
4339         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
4340         touch .foo && error "touch .foo worked after removing cwd"
4341         mkdir .foo && error "mkdir .foo worked after removing cwd"
4342         $TRACE ls . && error "'ls .' worked after removing cwd"
4343         $TRACE ls .. || error "'ls ..' failed after removing cwd"
4344         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
4345         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
4346         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
4347         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
4348 }
4349 run_test 48c "Access removed working subdir (should return errors)"
4350
4351 test_48d() { # bug 2350
4352         #lctl set_param debug=-1
4353         #set -vx
4354         rm -rf $DIR/$tdir
4355         test_mkdir -p $DIR/$tdir/dir
4356         cd $DIR/$tdir/dir
4357         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4358         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4359         $TRACE touch foo && error "'touch foo' worked after removing parent"
4360         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
4361         touch .foo && error "'touch .foo' worked after removing parent"
4362         mkdir .foo && error "mkdir .foo worked after removing parent"
4363         $TRACE ls . && error "'ls .' worked after removing parent"
4364         $TRACE ls .. && error "'ls ..' worked after removing parent"
4365         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
4366         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
4367         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
4368         true
4369 }
4370 run_test 48d "Access removed parent subdir (should return errors)"
4371
4372 test_48e() { # bug 4134
4373         #lctl set_param debug=-1
4374         #set -vx
4375         rm -rf $DIR/$tdir
4376         test_mkdir -p $DIR/$tdir/dir
4377         cd $DIR/$tdir/dir
4378         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4379         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4380         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
4381         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
4382         # On a buggy kernel addition of "touch foo" after cd .. will
4383         # produce kernel oops in lookup_hash_it
4384         touch ../foo && error "'cd ..' worked after recreate parent"
4385         cd $DIR
4386         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
4387 }
4388 run_test 48e "Access to recreated parent subdir (should return errors)"
4389
4390 test_49() { # LU-1030
4391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4392         remote_ost_nodsh && skip "remote OST with nodsh"
4393
4394         # get ost1 size - lustre-OST0000
4395         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
4396                 awk '{ print $4 }')
4397         # write 800M at maximum
4398         [[ $ost1_size -lt 2 ]] && ost1_size=2
4399         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
4400
4401         $LFS setstripe -c 1 -i 0 $DIR/$tfile
4402         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
4403         local dd_pid=$!
4404
4405         # change max_pages_per_rpc while writing the file
4406         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
4407         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
4408         # loop until dd process exits
4409         while ps ax -opid | grep -wq $dd_pid; do
4410                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
4411                 sleep $((RANDOM % 5 + 1))
4412         done
4413         # restore original max_pages_per_rpc
4414         $LCTL set_param $osc1_mppc=$orig_mppc
4415         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
4416 }
4417 run_test 49 "Change max_pages_per_rpc won't break osc extent"
4418
4419 test_50() {
4420         # bug 1485
4421         test_mkdir $DIR/$tdir
4422         cd $DIR/$tdir
4423         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
4424 }
4425 run_test 50 "special situations: /proc symlinks  ==============="
4426
4427 test_51a() {    # was test_51
4428         # bug 1516 - create an empty entry right after ".." then split dir
4429         test_mkdir -c1 $DIR/$tdir
4430         touch $DIR/$tdir/foo
4431         $MCREATE $DIR/$tdir/bar
4432         rm $DIR/$tdir/foo
4433         createmany -m $DIR/$tdir/longfile 201
4434         FNUM=202
4435         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
4436                 $MCREATE $DIR/$tdir/longfile$FNUM
4437                 FNUM=$(($FNUM + 1))
4438                 echo -n "+"
4439         done
4440         echo
4441         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
4442 }
4443 run_test 51a "special situations: split htree with empty entry =="
4444
4445 cleanup_print_lfs_df () {
4446         trap 0
4447         $LFS df
4448         $LFS df -i
4449 }
4450
4451 test_51b() {
4452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4453
4454         local dir=$DIR/$tdir
4455         local nrdirs=$((65536 + 100))
4456
4457         # cleanup the directory
4458         rm -fr $dir
4459
4460         test_mkdir -c1 $dir
4461
4462         $LFS df
4463         $LFS df -i
4464         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
4465         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
4466         [[ $numfree -lt $nrdirs ]] &&
4467                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
4468
4469         # need to check free space for the directories as well
4470         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
4471         numfree=$(( blkfree / $(fs_inode_ksize) ))
4472         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
4473
4474         trap cleanup_print_lfs_df EXIT
4475
4476         # create files
4477         createmany -d $dir/d $nrdirs || {
4478                 unlinkmany $dir/d $nrdirs
4479                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
4480         }
4481
4482         # really created :
4483         nrdirs=$(ls -U $dir | wc -l)
4484
4485         # unlink all but 100 subdirectories, then check it still works
4486         local left=100
4487         local delete=$((nrdirs - left))
4488
4489         $LFS df
4490         $LFS df -i
4491
4492         # for ldiskfs the nlink count should be 1, but this is OSD specific
4493         # and so this is listed for informational purposes only
4494         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
4495         unlinkmany -d $dir/d $delete ||
4496                 error "unlink of first $delete subdirs failed"
4497
4498         echo "nlink between: $(stat -c %h $dir)"
4499         local found=$(ls -U $dir | wc -l)
4500         [ $found -ne $left ] &&
4501                 error "can't find subdirs: found only $found, expected $left"
4502
4503         unlinkmany -d $dir/d $delete $left ||
4504                 error "unlink of second $left subdirs failed"
4505         # regardless of whether the backing filesystem tracks nlink accurately
4506         # or not, the nlink count shouldn't be more than "." and ".." here
4507         local after=$(stat -c %h $dir)
4508         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
4509                 echo "nlink after: $after"
4510
4511         cleanup_print_lfs_df
4512 }
4513 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
4514
4515 test_51d() {
4516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4517         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
4518
4519         test_mkdir $DIR/$tdir
4520         createmany -o $DIR/$tdir/t- 1000
4521         $LFS getstripe $DIR/$tdir > $TMP/$tfile
4522         for N in $(seq 0 $((OSTCOUNT - 1))); do
4523                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
4524                         END { printf("%0.0f", objs) }' $TMP/$tfile)
4525                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
4526                         '($1 == '$N') { objs += 1 } \
4527                         END { printf("%0.0f", objs) }')
4528                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
4529         done
4530         unlinkmany $DIR/$tdir/t- 1000
4531
4532         NLAST=0
4533         for N in $(seq 1 $((OSTCOUNT - 1))); do
4534                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
4535                         error "OST $N has less objects vs OST $NLAST" \
4536                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4537                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
4538                         error "OST $N has less objects vs OST $NLAST" \
4539                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4540
4541                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
4542                         error "OST $N has less #0 objects vs OST $NLAST" \
4543                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4544                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
4545                         error "OST $N has less #0 objects vs OST $NLAST" \
4546                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4547                 NLAST=$N
4548         done
4549         rm -f $TMP/$tfile
4550 }
4551 run_test 51d "check object distribution"
4552
4553 test_51e() {
4554         if [ "$mds1_FSTYPE" != ldiskfs ]; then
4555                 skip_env "ldiskfs only test"
4556         fi
4557
4558         test_mkdir -c1 $DIR/$tdir
4559         test_mkdir -c1 $DIR/$tdir/d0
4560
4561         touch $DIR/$tdir/d0/foo
4562         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
4563                 error "file exceed 65000 nlink limit!"
4564         unlinkmany $DIR/$tdir/d0/f- 65001
4565         return 0
4566 }
4567 run_test 51e "check file nlink limit"
4568
4569 test_51f() {
4570         test_mkdir $DIR/$tdir
4571
4572         local max=100000
4573         local ulimit_old=$(ulimit -n)
4574         local spare=20 # number of spare fd's for scripts/libraries, etc.
4575         local mdt=$($LFS getstripe -m $DIR/$tdir)
4576         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
4577
4578         echo "MDT$mdt numfree=$numfree, max=$max"
4579         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
4580         if [ $((numfree + spare)) -gt $ulimit_old ]; then
4581                 while ! ulimit -n $((numfree + spare)); do
4582                         numfree=$((numfree * 3 / 4))
4583                 done
4584                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
4585         else
4586                 echo "left ulimit at $ulimit_old"
4587         fi
4588
4589         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
4590                 unlinkmany $DIR/$tdir/f $numfree
4591                 error "create+open $numfree files in $DIR/$tdir failed"
4592         }
4593         ulimit -n $ulimit_old
4594
4595         # if createmany exits at 120s there will be fewer than $numfree files
4596         unlinkmany $DIR/$tdir/f $numfree || true
4597 }
4598 run_test 51f "check many open files limit"
4599
4600 test_52a() {
4601         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
4602         test_mkdir $DIR/$tdir
4603         touch $DIR/$tdir/foo
4604         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
4605         echo bar >> $DIR/$tdir/foo || error "append bar failed"
4606         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
4607         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
4608         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
4609                                         error "link worked"
4610         echo foo >> $DIR/$tdir/foo || error "append foo failed"
4611         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
4612         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
4613                                                      error "lsattr"
4614         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
4615         cp -r $DIR/$tdir $TMP/
4616         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
4617 }
4618 run_test 52a "append-only flag test (should return errors)"
4619
4620 test_52b() {
4621         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
4622         test_mkdir $DIR/$tdir
4623         touch $DIR/$tdir/foo
4624         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
4625         cat test > $DIR/$tdir/foo && error "cat test worked"
4626         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
4627         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
4628         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
4629                                         error "link worked"
4630         echo foo >> $DIR/$tdir/foo && error "echo worked"
4631         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
4632         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
4633         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
4634         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
4635                                                         error "lsattr"
4636         chattr -i $DIR/$tdir/foo || error "chattr failed"
4637
4638         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
4639 }
4640 run_test 52b "immutable flag test (should return errors) ======="
4641
4642 test_53() {
4643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4644         remote_mds_nodsh && skip "remote MDS with nodsh"
4645         remote_ost_nodsh && skip "remote OST with nodsh"
4646
4647         local param
4648         local param_seq
4649         local ostname
4650         local mds_last
4651         local mds_last_seq
4652         local ost_last
4653         local ost_last_seq
4654         local ost_last_id
4655         local ostnum
4656         local node
4657         local found=false
4658         local support_last_seq=true
4659
4660         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
4661                 support_last_seq=false
4662
4663         # only test MDT0000
4664         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
4665         local value
4666         for value in $(do_facet $SINGLEMDS \
4667                        $LCTL get_param osc.$mdtosc.prealloc_last_id) ; do
4668                 param=$(echo ${value[0]} | cut -d "=" -f1)
4669                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
4670
4671                 if $support_last_seq; then
4672                         param_seq=$(echo $param |
4673                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
4674                         mds_last_seq=$(do_facet $SINGLEMDS \
4675                                        $LCTL get_param -n $param_seq)
4676                 fi
4677                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
4678
4679                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
4680                 node=$(facet_active_host ost$((ostnum+1)))
4681                 param="obdfilter.$ostname.last_id"
4682                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
4683                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
4684                         ost_last_id=$ost_last
4685
4686                         if $support_last_seq; then
4687                                 ost_last_id=$(echo $ost_last |
4688                                               awk -F':' '{print $2}' |
4689                                               sed -e "s/^0x//g")
4690                                 ost_last_seq=$(echo $ost_last |
4691                                                awk -F':' '{print $1}')
4692                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
4693                         fi
4694
4695                         if [[ $ost_last_id != $mds_last ]]; then
4696                                 error "$ost_last_id != $mds_last"
4697                         else
4698                                 found=true
4699                                 break
4700                         fi
4701                 done
4702         done
4703         $found || error "can not match last_seq/last_id for $mdtosc"
4704         return 0
4705 }
4706 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
4707
4708 test_54a() {
4709         perl -MSocket -e ';' || skip "no Socket perl module installed"
4710
4711         $SOCKETSERVER $DIR/socket ||
4712                 error "$SOCKETSERVER $DIR/socket failed: $?"
4713         $SOCKETCLIENT $DIR/socket ||
4714                 error "$SOCKETCLIENT $DIR/socket failed: $?"
4715         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
4716 }
4717 run_test 54a "unix domain socket test =========================="
4718
4719 test_54b() {
4720         f="$DIR/f54b"
4721         mknod $f c 1 3
4722         chmod 0666 $f
4723         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
4724 }
4725 run_test 54b "char device works in lustre ======================"
4726
4727 find_loop_dev() {
4728         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
4729         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
4730         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
4731
4732         for i in $(seq 3 7); do
4733                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
4734                 LOOPDEV=$LOOPBASE$i
4735                 LOOPNUM=$i
4736                 break
4737         done
4738 }
4739
4740 cleanup_54c() {
4741         local rc=0
4742         loopdev="$DIR/loop54c"
4743
4744         trap 0
4745         $UMOUNT $DIR/$tdir || rc=$?
4746         losetup -d $loopdev || true
4747         losetup -d $LOOPDEV || true
4748         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
4749         return $rc
4750 }
4751
4752 test_54c() {
4753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4754
4755         loopdev="$DIR/loop54c"
4756
4757         find_loop_dev
4758         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
4759         trap cleanup_54c EXIT
4760         mknod $loopdev b 7 $LOOPNUM
4761         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
4762         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
4763         losetup $loopdev $DIR/$tfile ||
4764                 error "can't set up $loopdev for $DIR/$tfile"
4765         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
4766         test_mkdir $DIR/$tdir
4767         mount -t ext2 $loopdev $DIR/$tdir ||
4768                 error "error mounting $loopdev on $DIR/$tdir"
4769         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
4770                 error "dd write"
4771         df $DIR/$tdir
4772         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
4773                 error "dd read"
4774         cleanup_54c
4775 }
4776 run_test 54c "block device works in lustre ====================="
4777
4778 test_54d() {
4779         f="$DIR/f54d"
4780         string="aaaaaa"
4781         mknod $f p
4782         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
4783 }
4784 run_test 54d "fifo device works in lustre ======================"
4785
4786 test_54e() {
4787         f="$DIR/f54e"
4788         string="aaaaaa"
4789         cp -aL /dev/console $f
4790         echo $string > $f || error "echo $string to $f failed"
4791 }
4792 run_test 54e "console/tty device works in lustre ======================"
4793
4794 test_56a() {
4795         local numfiles=3
4796         local dir=$DIR/$tdir
4797
4798         rm -rf $dir
4799         test_mkdir -p $dir/dir
4800         for i in $(seq $numfiles); do
4801                 touch $dir/file$i
4802                 touch $dir/dir/file$i
4803         done
4804
4805         local numcomp=$($LFS getstripe --component-count $dir)
4806
4807         [[ $numcomp == 0 ]] && numcomp=1
4808
4809         # test lfs getstripe with --recursive
4810         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
4811
4812         [[ $filenum -eq $((numfiles * 2)) ]] ||
4813                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
4814         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
4815         [[ $filenum -eq $numfiles ]] ||
4816                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
4817         echo "$LFS getstripe showed obdidx or l_ost_idx"
4818
4819         # test lfs getstripe with file instead of dir
4820         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
4821         [[ $filenum -eq 1 ]] ||
4822                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
4823         echo "$LFS getstripe file1 passed"
4824
4825         #test lfs getstripe with --verbose
4826         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
4827         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
4828                 error "$LFS getstripe --verbose $dir: "\
4829                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
4830         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
4831                 error "$LFS getstripe $dir: showed lmm_magic"
4832
4833         #test lfs getstripe with -v prints lmm_fid
4834         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
4835         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
4836                 error "$LFS getstripe -v $dir: "\
4837                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
4838         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
4839                 error "$LFS getstripe $dir: showed lmm_fid by default"
4840         echo "$LFS getstripe --verbose passed"
4841
4842         #check for FID information
4843         local fid1=$($LFS getstripe --fid $dir/file1)
4844         local fid2=$($LFS getstripe --verbose $dir/file1 |
4845                      awk '/lmm_fid: / { print $2; exit; }')
4846         local fid3=$($LFS path2fid $dir/file1)
4847
4848         [ "$fid1" != "$fid2" ] &&
4849                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
4850         [ "$fid1" != "$fid3" ] &&
4851                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
4852         echo "$LFS getstripe --fid passed"
4853
4854         #test lfs getstripe with --obd
4855         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
4856                 error "$LFS getstripe --obd wrong_uuid: should return error"
4857
4858         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4859
4860         local ostidx=1
4861         local obduuid=$(ostuuid_from_index $ostidx)
4862         local found=$($LFS getstripe -r --obd $obduuid $dir |
4863                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
4864
4865         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
4866         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
4867                 ((filenum--))
4868         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
4869                 ((filenum--))
4870
4871         [[ $found -eq $filenum ]] ||
4872                 error "$LFS getstripe --obd: found $found expect $filenum"
4873         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
4874                 sed '/^[         ]*'${ostidx}'[  ]/d' |
4875                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
4876                 error "$LFS getstripe --obd: should not show file on other obd"
4877         echo "$LFS getstripe --obd passed"
4878 }
4879 run_test 56a "check $LFS getstripe"
4880
4881 test_56b() {
4882         local dir=$DIR/$tdir
4883         local numdirs=3
4884
4885         test_mkdir $dir
4886         for i in $(seq $numdirs); do
4887                 test_mkdir $dir/dir$i
4888         done
4889
4890         # test lfs getdirstripe default mode is non-recursion, which is
4891         # different from lfs getstripe
4892         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
4893
4894         [[ $dircnt -eq 1 ]] ||
4895                 error "$LFS getdirstripe: found $dircnt, not 1"
4896         dircnt=$($LFS getdirstripe --recursive $dir |
4897                 grep -c lmv_stripe_count)
4898         [[ $dircnt -eq $((numdirs + 1)) ]] ||
4899                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
4900 }
4901 run_test 56b "check $LFS getdirstripe"
4902
4903 test_56c() {
4904         remote_ost_nodsh && skip "remote OST with nodsh"
4905
4906         local ost_idx=0
4907         local ost_name=$(ostname_from_index $ost_idx)
4908         local old_status=$(ost_dev_status $ost_idx)
4909
4910         [[ -z "$old_status" ]] ||
4911                 skip_env "OST $ost_name is in $old_status status"
4912
4913         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
4914         sleep_maxage
4915
4916         local new_status=$(ost_dev_status $ost_idx)
4917
4918         [[ "$new_status" = "D" ]] ||
4919                 error "OST $ost_name is in status of '$new_status', not 'D'"
4920
4921         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
4922         sleep_maxage
4923
4924         new_status=$(ost_dev_status $ost_idx)
4925         [[ -z "$new_status" ]] ||
4926                 error "OST $ost_name is in status of '$new_status', not ''"
4927 }
4928 run_test 56c "check 'lfs df' showing device status"
4929
4930 NUMFILES=3
4931 NUMDIRS=3
4932 setup_56() {
4933         local local_tdir="$1"
4934         local local_numfiles="$2"
4935         local local_numdirs="$3"
4936         local dir_params="$4"
4937         local dir_stripe_params="$5"
4938
4939         if [ ! -d "$local_tdir" ] ; then
4940                 test_mkdir -p $dir_stripe_params $local_tdir
4941                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
4942                 for i in $(seq $local_numfiles) ; do
4943                         touch $local_tdir/file$i
4944                 done
4945                 for i in $(seq $local_numdirs) ; do
4946                         test_mkdir $dir_stripe_params $local_tdir/dir$i
4947                         for j in $(seq $local_numfiles) ; do
4948                                 touch $local_tdir/dir$i/file$j
4949                         done
4950                 done
4951         fi
4952 }
4953
4954 setup_56_special() {
4955         local local_tdir=$1
4956         local local_numfiles=$2
4957         local local_numdirs=$3
4958
4959         setup_56 $local_tdir $local_numfiles $local_numdirs
4960
4961         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
4962                 for i in $(seq $local_numfiles) ; do
4963                         mknod $local_tdir/loop${i}b b 7 $i
4964                         mknod $local_tdir/null${i}c c 1 3
4965                         ln -s $local_tdir/file1 $local_tdir/link${i}
4966                 done
4967                 for i in $(seq $local_numdirs) ; do
4968                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
4969                         mknod $local_tdir/dir$i/null${i}c c 1 3
4970                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
4971                 done
4972         fi
4973 }
4974
4975 test_56g() {
4976         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
4977         local expected=$(($NUMDIRS + 2))
4978
4979         setup_56 $dir $NUMFILES $NUMDIRS
4980
4981         # test lfs find with -name
4982         for i in $(seq $NUMFILES) ; do
4983                 local nums=$($LFS find -name "*$i" $dir | wc -l)
4984
4985                 [ $nums -eq $expected ] ||
4986                         error "lfs find -name '*$i' $dir wrong: "\
4987                               "found $nums, expected $expected"
4988         done
4989 }
4990 run_test 56g "check lfs find -name"
4991
4992 test_56h() {
4993         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
4994         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
4995
4996         setup_56 $dir $NUMFILES $NUMDIRS
4997
4998         # test lfs find with ! -name
4999         for i in $(seq $NUMFILES) ; do
5000                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5001
5002                 [ $nums -eq $expected ] ||
5003                         error "lfs find ! -name '*$i' $dir wrong: "\
5004                               "found $nums, expected $expected"
5005         done
5006 }
5007 run_test 56h "check lfs find ! -name"
5008
5009 test_56i() {
5010         local dir=$DIR/$tdir
5011
5012         test_mkdir $dir
5013
5014         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5015         local out=$($cmd)
5016
5017         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5018 }
5019 run_test 56i "check 'lfs find -ost UUID' skips directories"
5020
5021 test_56j() {
5022         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5023
5024         setup_56_special $dir $NUMFILES $NUMDIRS
5025
5026         local expected=$((NUMDIRS + 1))
5027         local cmd="$LFS find -type d $dir"
5028         local nums=$($cmd | wc -l)
5029
5030         [ $nums -eq $expected ] ||
5031                 error "'$cmd' wrong: found $nums, expected $expected"
5032 }
5033 run_test 56j "check lfs find -type d"
5034
5035 test_56k() {
5036         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5037
5038         setup_56_special $dir $NUMFILES $NUMDIRS
5039
5040         local expected=$(((NUMDIRS + 1) * NUMFILES))
5041         local cmd="$LFS find -type f $dir"
5042         local nums=$($cmd | wc -l)
5043
5044         [ $nums -eq $expected ] ||
5045                 error "'$cmd' wrong: found $nums, expected $expected"
5046 }
5047 run_test 56k "check lfs find -type f"
5048
5049 test_56l() {
5050         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5051
5052         setup_56_special $dir $NUMFILES $NUMDIRS
5053
5054         local expected=$((NUMDIRS + NUMFILES))
5055         local cmd="$LFS find -type b $dir"
5056         local nums=$($cmd | wc -l)
5057
5058         [ $nums -eq $expected ] ||
5059                 error "'$cmd' wrong: found $nums, expected $expected"
5060 }
5061 run_test 56l "check lfs find -type b"
5062
5063 test_56m() {
5064         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5065
5066         setup_56_special $dir $NUMFILES $NUMDIRS
5067
5068         local expected=$((NUMDIRS + NUMFILES))
5069         local cmd="$LFS find -type c $dir"
5070         local nums=$($cmd | wc -l)
5071         [ $nums -eq $expected ] ||
5072                 error "'$cmd' wrong: found $nums, expected $expected"
5073 }
5074 run_test 56m "check lfs find -type c"
5075
5076 test_56n() {
5077         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5078         setup_56_special $dir $NUMFILES $NUMDIRS
5079
5080         local expected=$((NUMDIRS + NUMFILES))
5081         local cmd="$LFS find -type l $dir"
5082         local nums=$($cmd | wc -l)
5083
5084         [ $nums -eq $expected ] ||
5085                 error "'$cmd' wrong: found $nums, expected $expected"
5086 }
5087 run_test 56n "check lfs find -type l"
5088
5089 test_56o() {
5090         local dir=$DIR/$tdir
5091
5092         setup_56 $dir $NUMFILES $NUMDIRS
5093         utime $dir/file1 > /dev/null || error "utime (1)"
5094         utime $dir/file2 > /dev/null || error "utime (2)"
5095         utime $dir/dir1 > /dev/null || error "utime (3)"
5096         utime $dir/dir2 > /dev/null || error "utime (4)"
5097         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5098         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5099
5100         local expected=4
5101         local nums=$($LFS find -mtime +0 $dir | wc -l)
5102
5103         [ $nums -eq $expected ] ||
5104                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5105
5106         expected=12
5107         cmd="$LFS find -mtime 0 $dir"
5108         nums=$($cmd | wc -l)
5109         [ $nums -eq $expected ] ||
5110                 error "'$cmd' wrong: found $nums, expected $expected"
5111 }
5112 run_test 56o "check lfs find -mtime for old files"
5113
5114 test_56ob() {
5115         local dir=$DIR/$tdir
5116         local expected=1
5117         local count=0
5118
5119         # just to make sure there is something that won't be found
5120         test_mkdir $dir
5121         touch $dir/$tfile.now
5122
5123         for age in year week day hour min; do
5124                 count=$((count + 1))
5125
5126                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5127                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5128                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5129
5130                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5131                 local nums=$($cmd | wc -l)
5132                 [ $nums -eq $expected ] ||
5133                         error "'$cmd' wrong: found $nums, expected $expected"
5134
5135                 cmd="$LFS find $dir -atime $count${age:0:1}"
5136                 nums=$($cmd | wc -l)
5137                 [ $nums -eq $expected ] ||
5138                         error "'$cmd' wrong: found $nums, expected $expected"
5139         done
5140
5141         sleep 2
5142         cmd="$LFS find $dir -ctime +1s -type f"
5143         nums=$($cmd | wc -l)
5144         (( $nums == $count * 2 + 1)) ||
5145                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5146 }
5147 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5148
5149 test_56p() {
5150         [ $RUNAS_ID -eq $UID ] &&
5151                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5152
5153         local dir=$DIR/$tdir
5154
5155         setup_56 $dir $NUMFILES $NUMDIRS
5156         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5157
5158         local expected=$NUMFILES
5159         local cmd="$LFS find -uid $RUNAS_ID $dir"
5160         local nums=$($cmd | wc -l)
5161
5162         [ $nums -eq $expected ] ||
5163                 error "'$cmd' wrong: found $nums, expected $expected"
5164
5165         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5166         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5167         nums=$($cmd | wc -l)
5168         [ $nums -eq $expected ] ||
5169                 error "'$cmd' wrong: found $nums, expected $expected"
5170 }
5171 run_test 56p "check lfs find -uid and ! -uid"
5172
5173 test_56q() {
5174         [ $RUNAS_ID -eq $UID ] &&
5175                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5176
5177         local dir=$DIR/$tdir
5178
5179         setup_56 $dir $NUMFILES $NUMDIRS
5180         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5181
5182         local expected=$NUMFILES
5183         local cmd="$LFS find -gid $RUNAS_GID $dir"
5184         local nums=$($cmd | wc -l)
5185
5186         [ $nums -eq $expected ] ||
5187                 error "'$cmd' wrong: found $nums, expected $expected"
5188
5189         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5190         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5191         nums=$($cmd | wc -l)
5192         [ $nums -eq $expected ] ||
5193                 error "'$cmd' wrong: found $nums, expected $expected"
5194 }
5195 run_test 56q "check lfs find -gid and ! -gid"
5196
5197 test_56r() {
5198         local dir=$DIR/$tdir
5199
5200         setup_56 $dir $NUMFILES $NUMDIRS
5201
5202         local expected=12
5203         local cmd="$LFS find -size 0 -type f $dir"
5204         local nums=$($cmd | wc -l)
5205
5206         [ $nums -eq $expected ] ||
5207                 error "'$cmd' wrong: found $nums, expected $expected"
5208         expected=0
5209         cmd="$LFS find ! -size 0 -type f $dir"
5210         nums=$($cmd | wc -l)
5211         [ $nums -eq $expected ] ||
5212                 error "'$cmd' wrong: found $nums, expected $expected"
5213         echo "test" > $dir/$tfile
5214         echo "test2" > $dir/$tfile.2 && sync
5215         expected=1
5216         cmd="$LFS find -size 5 -type f $dir"
5217         nums=$($cmd | wc -l)
5218         [ $nums -eq $expected ] ||
5219                 error "'$cmd' wrong: found $nums, expected $expected"
5220         expected=1
5221         cmd="$LFS find -size +5 -type f $dir"
5222         nums=$($cmd | wc -l)
5223         [ $nums -eq $expected ] ||
5224                 error "'$cmd' wrong: found $nums, expected $expected"
5225         expected=2
5226         cmd="$LFS find -size +0 -type f $dir"
5227         nums=$($cmd | wc -l)
5228         [ $nums -eq $expected ] ||
5229                 error "'$cmd' wrong: found $nums, expected $expected"
5230         expected=2
5231         cmd="$LFS find ! -size -5 -type f $dir"
5232         nums=$($cmd | wc -l)
5233         [ $nums -eq $expected ] ||
5234                 error "'$cmd' wrong: found $nums, expected $expected"
5235         expected=12
5236         cmd="$LFS find -size -5 -type f $dir"
5237         nums=$($cmd | wc -l)
5238         [ $nums -eq $expected ] ||
5239                 error "'$cmd' wrong: found $nums, expected $expected"
5240 }
5241 run_test 56r "check lfs find -size works"
5242
5243 test_56s() { # LU-611 #LU-9369
5244         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
5245
5246         local dir=$DIR/$tdir
5247         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
5248
5249         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
5250         for i in $(seq $NUMDIRS); do
5251                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
5252         done
5253
5254         local expected=$NUMDIRS
5255         local cmd="$LFS find -c $OSTCOUNT $dir"
5256         local nums=$($cmd | wc -l)
5257
5258         [ $nums -eq $expected ] || {
5259                 $LFS getstripe -R $dir
5260                 error "'$cmd' wrong: found $nums, expected $expected"
5261         }
5262
5263         expected=$((NUMDIRS + onestripe))
5264         cmd="$LFS find -stripe-count +0 -type f $dir"
5265         nums=$($cmd | wc -l)
5266         [ $nums -eq $expected ] || {
5267                 $LFS getstripe -R $dir
5268                 error "'$cmd' wrong: found $nums, expected $expected"
5269         }
5270
5271         expected=$onestripe
5272         cmd="$LFS find -stripe-count 1 -type f $dir"
5273         nums=$($cmd | wc -l)
5274         [ $nums -eq $expected ] || {
5275                 $LFS getstripe -R $dir
5276                 error "'$cmd' wrong: found $nums, expected $expected"
5277         }
5278
5279         cmd="$LFS find -stripe-count -2 -type f $dir"
5280         nums=$($cmd | wc -l)
5281         [ $nums -eq $expected ] || {
5282                 $LFS getstripe -R $dir
5283                 error "'$cmd' wrong: found $nums, expected $expected"
5284         }
5285
5286         expected=0
5287         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
5288         nums=$($cmd | wc -l)
5289         [ $nums -eq $expected ] || {
5290                 $LFS getstripe -R $dir
5291                 error "'$cmd' wrong: found $nums, expected $expected"
5292         }
5293 }
5294 run_test 56s "check lfs find -stripe-count works"
5295
5296 test_56t() { # LU-611 #LU-9369
5297         local dir=$DIR/$tdir
5298
5299         setup_56 $dir 0 $NUMDIRS
5300         for i in $(seq $NUMDIRS); do
5301                 $LFS setstripe -S 8M $dir/dir$i/$tfile
5302         done
5303
5304         local expected=$NUMDIRS
5305         local cmd="$LFS find -S 8M $dir"
5306         local nums=$($cmd | wc -l)
5307
5308         [ $nums -eq $expected ] || {
5309                 $LFS getstripe -R $dir
5310                 error "'$cmd' wrong: found $nums, expected $expected"
5311         }
5312         rm -rf $dir
5313
5314         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
5315
5316         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
5317
5318         expected=$(((NUMDIRS + 1) * NUMFILES))
5319         cmd="$LFS find -stripe-size 512k -type f $dir"
5320         nums=$($cmd | wc -l)
5321         [ $nums -eq $expected ] ||
5322                 error "'$cmd' wrong: found $nums, expected $expected"
5323
5324         cmd="$LFS find -stripe-size +320k -type f $dir"
5325         nums=$($cmd | wc -l)
5326         [ $nums -eq $expected ] ||
5327                 error "'$cmd' wrong: found $nums, expected $expected"
5328
5329         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
5330         cmd="$LFS find -stripe-size +200k -type f $dir"
5331         nums=$($cmd | wc -l)
5332         [ $nums -eq $expected ] ||
5333                 error "'$cmd' wrong: found $nums, expected $expected"
5334
5335         cmd="$LFS find -stripe-size -640k -type f $dir"
5336         nums=$($cmd | wc -l)
5337         [ $nums -eq $expected ] ||
5338                 error "'$cmd' wrong: found $nums, expected $expected"
5339
5340         expected=4
5341         cmd="$LFS find -stripe-size 256k -type f $dir"
5342         nums=$($cmd | wc -l)
5343         [ $nums -eq $expected ] ||
5344                 error "'$cmd' wrong: found $nums, expected $expected"
5345
5346         cmd="$LFS find -stripe-size -320k -type f $dir"
5347         nums=$($cmd | wc -l)
5348         [ $nums -eq $expected ] ||
5349                 error "'$cmd' wrong: found $nums, expected $expected"
5350
5351         expected=0
5352         cmd="$LFS find -stripe-size 1024k -type f $dir"
5353         nums=$($cmd | wc -l)
5354         [ $nums -eq $expected ] ||
5355                 error "'$cmd' wrong: found $nums, expected $expected"
5356 }
5357 run_test 56t "check lfs find -stripe-size works"
5358
5359 test_56u() { # LU-611
5360         local dir=$DIR/$tdir
5361
5362         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
5363
5364         if [[ $OSTCOUNT -gt 1 ]]; then
5365                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
5366                 onestripe=4
5367         else
5368                 onestripe=0
5369         fi
5370
5371         local expected=$(((NUMDIRS + 1) * NUMFILES))
5372         local cmd="$LFS find -stripe-index 0 -type f $dir"
5373         local nums=$($cmd | wc -l)
5374
5375         [ $nums -eq $expected ] ||
5376                 error "'$cmd' wrong: found $nums, expected $expected"
5377
5378         expected=$onestripe
5379         cmd="$LFS find -stripe-index 1 -type f $dir"
5380         nums=$($cmd | wc -l)
5381         [ $nums -eq $expected ] ||
5382                 error "'$cmd' wrong: found $nums, expected $expected"
5383
5384         cmd="$LFS find ! -stripe-index 0 -type f $dir"
5385         nums=$($cmd | wc -l)
5386         [ $nums -eq $expected ] ||
5387                 error "'$cmd' wrong: found $nums, expected $expected"
5388
5389         expected=0
5390         # This should produce an error and not return any files
5391         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
5392         nums=$($cmd 2>/dev/null | wc -l)
5393         [ $nums -eq $expected ] ||
5394                 error "'$cmd' wrong: found $nums, expected $expected"
5395
5396         if [[ $OSTCOUNT -gt 1 ]]; then
5397                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
5398                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
5399                 nums=$($cmd | wc -l)
5400                 [ $nums -eq $expected ] ||
5401                         error "'$cmd' wrong: found $nums, expected $expected"
5402         fi
5403 }
5404 run_test 56u "check lfs find -stripe-index works"
5405
5406 test_56v() {
5407         local mdt_idx=0
5408         local dir=$DIR/$tdir
5409
5410         setup_56 $dir $NUMFILES $NUMDIRS
5411
5412         UUID=$(mdtuuid_from_index $mdt_idx $dir)
5413         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
5414
5415         for file in $($LFS find -m $UUID $dir); do
5416                 file_midx=$($LFS getstripe -m $file)
5417                 [ $file_midx -eq $mdt_idx ] ||
5418                         error "lfs find -m $UUID != getstripe -m $file_midx"
5419         done
5420 }
5421 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
5422
5423 test_56w() {
5424         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5426
5427         local dir=$DIR/$tdir
5428
5429         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
5430
5431         local stripe_size=$($LFS getstripe -S -d $dir) ||
5432                 error "$LFS getstripe -S -d $dir failed"
5433         stripe_size=${stripe_size%% *}
5434
5435         local file_size=$((stripe_size * OSTCOUNT))
5436         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
5437         local required_space=$((file_num * file_size))
5438         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
5439                            head -n1)
5440         [[ $free_space -le $((required_space / 1024)) ]] &&
5441                 skip_env "need $required_space, have $free_space kbytes"
5442
5443         local dd_bs=65536
5444         local dd_count=$((file_size / dd_bs))
5445
5446         # write data into the files
5447         local i
5448         local j
5449         local file
5450
5451         for i in $(seq $NUMFILES); do
5452                 file=$dir/file$i
5453                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5454                         error "write data into $file failed"
5455         done
5456         for i in $(seq $NUMDIRS); do
5457                 for j in $(seq $NUMFILES); do
5458                         file=$dir/dir$i/file$j
5459                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5460                                 error "write data into $file failed"
5461                 done
5462         done
5463
5464         # $LFS_MIGRATE will fail if hard link migration is unsupported
5465         if [[ $(lustre_version_code mds1) -gt $(version_code 2.5.55) ]]; then
5466                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
5467                         error "creating links to $dir/dir1/file1 failed"
5468         fi
5469
5470         local expected=-1
5471
5472         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
5473
5474         # lfs_migrate file
5475         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
5476
5477         echo "$cmd"
5478         eval $cmd || error "$cmd failed"
5479
5480         check_stripe_count $dir/file1 $expected
5481
5482         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
5483         then
5484                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
5485                 # OST 1 if it is on OST 0. This file is small enough to
5486                 # be on only one stripe.
5487                 file=$dir/migr_1_ost
5488                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
5489                         error "write data into $file failed"
5490                 local obdidx=$($LFS getstripe -i $file)
5491                 local oldmd5=$(md5sum $file)
5492                 local newobdidx=0
5493
5494                 [[ $obdidx -eq 0 ]] && newobdidx=1
5495                 cmd="$LFS migrate -i $newobdidx $file"
5496                 echo $cmd
5497                 eval $cmd || error "$cmd failed"
5498
5499                 local realobdix=$($LFS getstripe -i $file)
5500                 local newmd5=$(md5sum $file)
5501
5502                 [[ $newobdidx -ne $realobdix ]] &&
5503                         error "new OST is different (was=$obdidx, "\
5504                               "wanted=$newobdidx, got=$realobdix)"
5505                 [[ "$oldmd5" != "$newmd5" ]] &&
5506                         error "md5sum differ: $oldmd5, $newmd5"
5507         fi
5508
5509         # lfs_migrate dir
5510         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
5511         echo "$cmd"
5512         eval $cmd || error "$cmd failed"
5513
5514         for j in $(seq $NUMFILES); do
5515                 check_stripe_count $dir/dir1/file$j $expected
5516         done
5517
5518         # lfs_migrate works with lfs find
5519         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
5520              $LFS_MIGRATE -y -c $expected"
5521         echo "$cmd"
5522         eval $cmd || error "$cmd failed"
5523
5524         for i in $(seq 2 $NUMFILES); do
5525                 check_stripe_count $dir/file$i $expected
5526         done
5527         for i in $(seq 2 $NUMDIRS); do
5528                 for j in $(seq $NUMFILES); do
5529                 check_stripe_count $dir/dir$i/file$j $expected
5530                 done
5531         done
5532 }
5533 run_test 56w "check lfs_migrate -c stripe_count works"
5534
5535 test_56wb() {
5536         local file1=$DIR/$tdir/file1
5537         local create_pool=false
5538         local initial_pool=$($LFS getstripe -p $DIR)
5539         local pool_list=()
5540         local pool=""
5541
5542         echo -n "Creating test dir..."
5543         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5544         echo "done."
5545
5546         echo -n "Creating test file..."
5547         touch $file1 || error "cannot create file"
5548         echo "done."
5549
5550         echo -n "Detecting existing pools..."
5551         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
5552
5553         if [ ${#pool_list[@]} -gt 0 ]; then
5554                 echo "${pool_list[@]}"
5555                 for thispool in "${pool_list[@]}"; do
5556                         if [[ -z "$initial_pool" ||
5557                               "$initial_pool" != "$thispool" ]]; then
5558                                 pool="$thispool"
5559                                 echo "Using existing pool '$pool'"
5560                                 break
5561                         fi
5562                 done
5563         else
5564                 echo "none detected."
5565         fi
5566         if [ -z "$pool" ]; then
5567                 pool=${POOL:-testpool}
5568                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
5569                 echo -n "Creating pool '$pool'..."
5570                 create_pool=true
5571                 pool_add $pool &> /dev/null ||
5572                         error "pool_add failed"
5573                 echo "done."
5574
5575                 echo -n "Adding target to pool..."
5576                 pool_add_targets $pool 0 0 1 &> /dev/null ||
5577                         error "pool_add_targets failed"
5578                 echo "done."
5579         fi
5580
5581         echo -n "Setting pool using -p option..."
5582         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
5583                 error "migrate failed rc = $?"
5584         echo "done."
5585
5586         echo -n "Verifying test file is in pool after migrating..."
5587         [ "$($LFS getstripe -p $file1)" = $pool ] ||
5588                 error "file was not migrated to pool $pool"
5589         echo "done."
5590
5591         echo -n "Removing test file from pool '$pool'..."
5592         $LFS migrate $file1 &> /dev/null ||
5593                 error "cannot remove from pool"
5594         [ "$($LFS getstripe -p $file1)" ] &&
5595                 error "pool still set"
5596         echo "done."
5597
5598         echo -n "Setting pool using --pool option..."
5599         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
5600                 error "migrate failed rc = $?"
5601         echo "done."
5602
5603         # Clean up
5604         rm -f $file1
5605         if $create_pool; then
5606                 destroy_test_pools 2> /dev/null ||
5607                         error "destroy test pools failed"
5608         fi
5609 }
5610 run_test 56wb "check lfs_migrate pool support"
5611
5612 test_56wc() {
5613         local file1="$DIR/$tdir/file1"
5614
5615         echo -n "Creating test dir..."
5616         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5617         local def_stripe_size=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
5618         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
5619                 error "cannot set stripe"
5620         echo "done"
5621
5622         echo -n "Setting initial stripe for test file..."
5623         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
5624                 error "cannot set stripe"
5625         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
5626                 error "stripe size not set"
5627         echo "done."
5628
5629         # File currently set to -S 512K -c 1
5630
5631         # Ensure -c and -S options are rejected when -R is set
5632         echo -n "Verifying incompatible options are detected..."
5633         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
5634                 error "incompatible -c and -R options not detected"
5635         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
5636                 error "incompatible -S and -R options not detected"
5637         echo "done."
5638
5639         # Ensure unrecognized options are passed through to 'lfs migrate'
5640         echo -n "Verifying -S option is passed through to lfs migrate..."
5641         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
5642                 error "migration failed"
5643         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
5644                 error "file was not restriped"
5645         echo "done."
5646
5647         # File currently set to -S 1M -c 1
5648
5649         # Ensure long options are supported
5650         echo -n "Verifying long options supported..."
5651         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
5652                 error "long option without argument not supported"
5653         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
5654                 error "long option with argument not supported"
5655         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
5656                 error "file not restriped with --stripe-size option"
5657         echo "done."
5658
5659         # File currently set to -S 512K -c 1
5660
5661         if [ "$OSTCOUNT" -gt 1 ]; then
5662                 echo -n "Verifying explicit stripe count can be set..."
5663                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
5664                         error "migrate failed"
5665                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
5666                         error "file not restriped to explicit count"
5667                 echo "done."
5668         fi
5669
5670         # File currently set to -S 512K -c 1 or -S 512K -c 2
5671
5672         # Ensure parent striping is used if -R is set, and no stripe
5673         # count or size is specified
5674         echo -n "Setting stripe for parent directory..."
5675         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
5676                 error "cannot set stripe"
5677         echo "done."
5678
5679         echo -n "Verifying restripe option uses parent stripe settings..."
5680         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
5681                 error "migrate failed"
5682         [ $($LFS getstripe -S "$file1") -eq $def_stripe_size ] ||
5683                 error "file not restriped to parent settings"
5684         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
5685                 error "file not restriped to parent settings"
5686         echo "done."
5687
5688         # File currently set to -S 1M -c 1
5689
5690         # Ensure striping is preserved if -R is not set, and no stripe
5691         # count or size is specified
5692         echo -n "Verifying striping size preserved when not specified..."
5693         local orig_stripe_size=$($LFS getstripe -S "$file1" 2>/dev/null)
5694         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
5695                 error "cannot set stripe on parent directory"
5696         $LFS_MIGRATE -y "$file1" &> /dev/null ||
5697                 error "migrate failed"
5698         [ $($LFS getstripe -S "$file1") -eq $orig_stripe_size ] ||
5699                 error "file was restriped"
5700         echo "done."
5701
5702         # Ensure file name properly detected when final option has no argument
5703         echo -n "Verifying file name properly detected..."
5704         $LFS_MIGRATE -y "$file1" &> /dev/null ||
5705                 error "file name interpreted as option argument"
5706         echo "done."
5707
5708         # Clean up
5709         rm -f "$file1"
5710 }
5711 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
5712
5713 test_56wd() {
5714         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5715
5716         local file1=$DIR/$tdir/file1
5717
5718         echo -n "Creating test dir..."
5719         test_mkdir $DIR/$tdir || error "cannot create dir"
5720         echo "done."
5721
5722         echo -n "Creating test file..."
5723         touch $file1
5724         echo "done."
5725
5726         # Ensure 'lfs migrate' will fail by using a non-existent option,
5727         # and make sure rsync is not called to recover
5728         echo -n "Make sure --no-rsync option works..."
5729         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
5730                 grep -q 'refusing to fall back to rsync' ||
5731                 error "rsync was called with --no-rsync set"
5732         echo "done."
5733
5734         # Ensure rsync is called without trying 'lfs migrate' first
5735         echo -n "Make sure --rsync option works..."
5736         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
5737                 grep -q 'falling back to rsync' &&
5738                 error "lfs migrate was called with --rsync set"
5739         echo "done."
5740
5741         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
5742         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
5743                 grep -q 'at the same time' ||
5744                 error "--rsync and --no-rsync accepted concurrently"
5745         echo "done."
5746
5747         # Clean up
5748         rm -f $file1
5749 }
5750 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
5751
5752 test_56x() {
5753         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5754         check_swap_layouts_support
5755
5756         local dir=$DIR/$tdir
5757         local ref1=/etc/passwd
5758         local file1=$dir/file1
5759
5760         test_mkdir $dir || error "creating dir $dir"
5761         $LFS setstripe -c 2 $file1
5762         cp $ref1 $file1
5763         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
5764         stripe=$($LFS getstripe -c $file1)
5765         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
5766         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
5767
5768         # clean up
5769         rm -f $file1
5770 }
5771 run_test 56x "lfs migration support"
5772
5773 test_56xa() {
5774         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5775         check_swap_layouts_support
5776
5777         local dir=$DIR/$tdir/$testnum
5778
5779         test_mkdir -p $dir
5780
5781         local ref1=/etc/passwd
5782         local file1=$dir/file1
5783
5784         $LFS setstripe -c 2 $file1
5785         cp $ref1 $file1
5786         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
5787
5788         local stripe=$($LFS getstripe -c $file1)
5789
5790         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
5791         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
5792
5793         # clean up
5794         rm -f $file1
5795 }
5796 run_test 56xa "lfs migration --block support"
5797
5798 check_migrate_links() {
5799         local dir="$1"
5800         local file1="$dir/file1"
5801         local begin="$2"
5802         local count="$3"
5803         local total_count=$(($begin + $count - 1))
5804         local symlink_count=10
5805         local uniq_count=10
5806
5807         if [ ! -f "$file1" ]; then
5808                 echo -n "creating initial file..."
5809                 $LFS setstripe -c 1 -S "512k" "$file1" ||
5810                         error "cannot setstripe initial file"
5811                 echo "done"
5812
5813                 echo -n "creating symlinks..."
5814                 for s in $(seq 1 $symlink_count); do
5815                         ln -s "$file1" "$dir/slink$s" ||
5816                                 error "cannot create symlinks"
5817                 done
5818                 echo "done"
5819
5820                 echo -n "creating nonlinked files..."
5821                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
5822                         error "cannot create nonlinked files"
5823                 echo "done"
5824         fi
5825
5826         # create hard links
5827         if [ ! -f "$dir/file$total_count" ]; then
5828                 echo -n "creating hard links $begin:$total_count..."
5829                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
5830                         /dev/null || error "cannot create hard links"
5831                 echo "done"
5832         fi
5833
5834         echo -n "checking number of hard links listed in xattrs..."
5835         local fid=$($LFS getstripe -F "$file1")
5836         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
5837
5838         echo "${#paths[*]}"
5839         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
5840                         skip "hard link list has unexpected size, skipping test"
5841         fi
5842         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
5843                         error "link names should exceed xattrs size"
5844         fi
5845
5846         echo -n "migrating files..."
5847         local migrate_out=$($LFS_MIGRATE -y -S '1m' $dir)
5848         local rc=$?
5849         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
5850         echo "done"
5851
5852         # make sure all links have been properly migrated
5853         echo -n "verifying files..."
5854         fid=$($LFS getstripe -F "$file1") ||
5855                 error "cannot get fid for file $file1"
5856         for i in $(seq 2 $total_count); do
5857                 local fid2=$($LFS getstripe -F $dir/file$i)
5858
5859                 [ "$fid2" == "$fid" ] ||
5860                         error "migrated hard link has mismatched FID"
5861         done
5862
5863         # make sure hard links were properly detected, and migration was
5864         # performed only once for the entire link set; nonlinked files should
5865         # also be migrated
5866         local actual=$(grep -c 'done migrate' <<< "$migrate_out")
5867         local expected=$(($uniq_count + 1))
5868
5869         [ "$actual" -eq  "$expected" ] ||
5870                 error "hard links individually migrated ($actual != $expected)"
5871
5872         # make sure the correct number of hard links are present
5873         local hardlinks=$(stat -c '%h' "$file1")
5874
5875         [ $hardlinks -eq $total_count ] ||
5876                 error "num hard links $hardlinks != $total_count"
5877         echo "done"
5878
5879         return 0
5880 }
5881
5882 test_56xb() {
5883         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
5884                 skip "Need MDS version at least 2.10.55"
5885
5886         local dir="$DIR/$tdir"
5887
5888         test_mkdir "$dir" || error "cannot create dir $dir"
5889
5890         echo "testing lfs migrate mode when all links fit within xattrs"
5891         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
5892
5893         echo "testing rsync mode when all links fit within xattrs"
5894         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
5895
5896         echo "testing lfs migrate mode when all links do not fit within xattrs"
5897         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
5898
5899         echo "testing rsync mode when all links do not fit within xattrs"
5900         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
5901
5902
5903         # clean up
5904         rm -rf $dir
5905 }
5906 run_test 56xb "lfs migration hard link support"
5907
5908 test_56xc() {
5909         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5910
5911         local dir="$DIR/$tdir"
5912
5913         test_mkdir "$dir" || error "cannot create dir $dir"
5914
5915         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
5916         echo -n "Setting initial stripe for 20MB test file..."
5917         $LFS setstripe -c 2 -i 0 "$dir/20mb" || error "cannot setstripe"
5918         echo "done"
5919         echo -n "Sizing 20MB test file..."
5920         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
5921         echo "done"
5922         echo -n "Verifying small file autostripe count is 1..."
5923         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" &> /dev/null ||
5924                 error "cannot migrate 20MB file"
5925         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
5926                 error "cannot get stripe for $dir/20mb"
5927         [ $stripe_count -eq 1 ] ||
5928                 error "unexpected stripe count $stripe_count for 20MB file"
5929         rm -f "$dir/20mb"
5930         echo "done"
5931
5932         # Test 2: File is small enough to fit within the available space on
5933         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
5934         # have at least an additional 1KB for each desired stripe for test 3
5935         echo -n "Setting stripe for 1GB test file..."
5936         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe"
5937         echo "done"
5938         echo -n "Sizing 1GB test file..."
5939         # File size is 1GB + 3KB
5940         truncate "$dir/1gb" 1073744896 &> /dev/null ||
5941                 error "cannot create 1GB test file"
5942         echo "done"
5943         echo -n "Migrating 1GB file..."
5944         $LFS_MIGRATE -y -A -C 1 "$dir/1gb" &> /dev/null ||
5945                 error "cannot migrate file"
5946         echo "done"
5947         echo -n "Verifying autostripe count is sqrt(n) + 1..."
5948         stripe_count=$($LFS getstripe -c "$dir/1gb") ||
5949                 error "cannot get stripe for $dir/1gb"
5950         [ $stripe_count -eq 2 ] ||
5951                 error "unexpected stripe count $stripe_count (expected 2)"
5952         echo "done"
5953
5954         # Test 3: File is too large to fit within the available space on
5955         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
5956         if [ $OSTCOUNT -ge 3 ]; then
5957                 # The required available space is calculated as
5958                 # file size (1GB + 3KB) / OST count (3).
5959                 local kb_per_ost=349526
5960
5961                 echo -n "Migrating 1GB file..."
5962                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" &>> \
5963                         /dev/null || error "cannot migrate file"
5964                 echo "done"
5965
5966                 stripe_count=$($LFS getstripe -c "$dir/1gb")
5967                 echo -n "Verifying autostripe count with limited space..."
5968                 [ "$stripe_count" -a $stripe_count -eq 3 ] ||
5969                         error "unexpected stripe count $stripe_count (wanted 3)"
5970                 echo "done"
5971         fi
5972
5973         # clean up
5974         rm -rf $dir
5975 }
5976 run_test 56xc "lfs migration autostripe"
5977
5978 test_56y() {
5979         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
5980                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
5981
5982         local res=""
5983         local dir=$DIR/$tdir
5984         local f1=$dir/file1
5985         local f2=$dir/file2
5986
5987         test_mkdir -p $dir || error "creating dir $dir"
5988         touch $f1 || error "creating std file $f1"
5989         $MULTIOP $f2 H2c || error "creating released file $f2"
5990
5991         # a directory can be raid0, so ask only for files
5992         res=$($LFS find $dir -L raid0 -type f | wc -l)
5993         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
5994
5995         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
5996         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
5997
5998         # only files can be released, so no need to force file search
5999         res=$($LFS find $dir -L released)
6000         [[ $res == $f2 ]] || error "search released: found $res != $f2"
6001
6002         res=$($LFS find $dir -type f \! -L released)
6003         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
6004 }
6005 run_test 56y "lfs find -L raid0|released"
6006
6007 test_56z() { # LU-4824
6008         # This checks to make sure 'lfs find' continues after errors
6009         # There are two classes of errors that should be caught:
6010         # - If multiple paths are provided, all should be searched even if one
6011         #   errors out
6012         # - If errors are encountered during the search, it should not terminate
6013         #   early
6014         local dir=$DIR/$tdir
6015         local i
6016
6017         test_mkdir $dir
6018         for i in d{0..9}; do
6019                 test_mkdir $dir/$i
6020         done
6021         touch $dir/d{0..9}/$tfile
6022         $LFS find $DIR/non_existent_dir $dir &&
6023                 error "$LFS find did not return an error"
6024         # Make a directory unsearchable. This should NOT be the last entry in
6025         # directory order.  Arbitrarily pick the 6th entry
6026         chmod 700 $($LFS find $dir -type d | sed '6!d')
6027
6028         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
6029
6030         # The user should be able to see 10 directories and 9 files
6031         [ $count == 19 ] || error "$LFS find did not continue after error"
6032 }
6033 run_test 56z "lfs find should continue after an error"
6034
6035 test_56aa() { # LU-5937
6036         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
6037
6038         local dir=$DIR/$tdir
6039
6040         mkdir $dir
6041         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
6042
6043         createmany -o $dir/striped_dir/${tfile}- 1024
6044         local dirs=$($LFS find --size +8k $dir/)
6045
6046         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
6047 }
6048 run_test 56aa "lfs find --size under striped dir"
6049
6050 test_56ab() { # LU-10705
6051         test_mkdir $DIR/$tdir
6052         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
6053         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
6054         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
6055         # Flush writes to ensure valid blocks.  Need to be more thorough for
6056         # ZFS, since blocks are not allocated/returned to client immediately.
6057         sync_all_data
6058         wait_zfs_commit ost1 2
6059         cancel_lru_locks osc
6060         ls -ls $DIR/$tdir
6061
6062         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
6063
6064         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
6065
6066         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
6067         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
6068
6069         rm -f $DIR/$tdir/$tfile.[123]
6070 }
6071 run_test 56ab "lfs find --blocks"
6072
6073 test_56ba() {
6074         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
6075                 skip "Need MDS version at least 2.10.50"
6076
6077         # Create composite files with one component
6078         local dir=$DIR/$tdir
6079
6080         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
6081         # Create composite files with three components
6082         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
6083         # Create non-composite files
6084         createmany -o $dir/${tfile}- 10
6085
6086         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
6087
6088         [[ $nfiles == 10 ]] ||
6089                 error "lfs find -E 1M found $nfiles != 10 files"
6090
6091         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
6092         [[ $nfiles == 25 ]] ||
6093                 error "lfs find ! -E 1M found $nfiles != 25 files"
6094
6095         # All files have a component that starts at 0
6096         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
6097         [[ $nfiles == 35 ]] ||
6098                 error "lfs find --component-start 0 - $nfiles != 35 files"
6099
6100         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
6101         [[ $nfiles == 15 ]] ||
6102                 error "lfs find --component-start 2M - $nfiles != 15 files"
6103
6104         # All files created here have a componenet that does not starts at 2M
6105         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
6106         [[ $nfiles == 35 ]] ||
6107                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
6108
6109         # Find files with a specified number of components
6110         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
6111         [[ $nfiles == 15 ]] ||
6112                 error "lfs find --component-count 3 - $nfiles != 15 files"
6113
6114         # Remember non-composite files have a component count of zero
6115         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
6116         [[ $nfiles == 10 ]] ||
6117                 error "lfs find --component-count 0 - $nfiles != 10 files"
6118
6119         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
6120         [[ $nfiles == 20 ]] ||
6121                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
6122
6123         # All files have a flag called "init"
6124         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
6125         [[ $nfiles == 35 ]] ||
6126                 error "lfs find --component-flags init - $nfiles != 35 files"
6127
6128         # Multi-component files will have a component not initialized
6129         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
6130         [[ $nfiles == 15 ]] ||
6131                 error "lfs find !--component-flags init - $nfiles != 15 files"
6132
6133         rm -rf $dir
6134
6135 }
6136 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
6137
6138 test_56ca() {
6139         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
6140                 skip "Need MDS version at least 2.10.57"
6141
6142         local td=$DIR/$tdir
6143         local tf=$td/$tfile
6144         local dir
6145         local nfiles
6146         local cmd
6147         local i
6148         local j
6149
6150         # create mirrored directories and mirrored files
6151         mkdir $td || error "mkdir $td failed"
6152         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
6153         createmany -o $tf- 10 || error "create $tf- failed"
6154
6155         for i in $(seq 2); do
6156                 dir=$td/dir$i
6157                 mkdir $dir || error "mkdir $dir failed"
6158                 $LFS mirror create -N$((3 + i)) $dir ||
6159                         error "create mirrored dir $dir failed"
6160                 createmany -o $dir/$tfile- 10 ||
6161                         error "create $dir/$tfile- failed"
6162         done
6163
6164         # change the states of some mirrored files
6165         echo foo > $tf-6
6166         for i in $(seq 2); do
6167                 dir=$td/dir$i
6168                 for j in $(seq 4 9); do
6169                         echo foo > $dir/$tfile-$j
6170                 done
6171         done
6172
6173         # find mirrored files with specific mirror count
6174         cmd="$LFS find --mirror-count 3 --type f $td"
6175         nfiles=$($cmd | wc -l)
6176         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
6177
6178         cmd="$LFS find ! --mirror-count 3 --type f $td"
6179         nfiles=$($cmd | wc -l)
6180         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
6181
6182         cmd="$LFS find --mirror-count +2 --type f $td"
6183         nfiles=$($cmd | wc -l)
6184         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6185
6186         cmd="$LFS find --mirror-count -6 --type f $td"
6187         nfiles=$($cmd | wc -l)
6188         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6189
6190         # find mirrored files with specific file state
6191         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
6192         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
6193
6194         cmd="$LFS find --mirror-state=ro --type f $td"
6195         nfiles=$($cmd | wc -l)
6196         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
6197
6198         cmd="$LFS find ! --mirror-state=ro --type f $td"
6199         nfiles=$($cmd | wc -l)
6200         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6201
6202         cmd="$LFS find --mirror-state=wp --type f $td"
6203         nfiles=$($cmd | wc -l)
6204         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6205
6206         cmd="$LFS find ! --mirror-state=sp --type f $td"
6207         nfiles=$($cmd | wc -l)
6208         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6209 }
6210 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
6211
6212 test_57a() {
6213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6214         # note test will not do anything if MDS is not local
6215         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6216                 skip_env "ldiskfs only test"
6217         fi
6218         remote_mds_nodsh && skip "remote MDS with nodsh"
6219
6220         local MNTDEV="osd*.*MDT*.mntdev"
6221         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
6222         [ -z "$DEV" ] && error "can't access $MNTDEV"
6223         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
6224                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
6225                         error "can't access $DEV"
6226                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
6227                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
6228                 rm $TMP/t57a.dump
6229         done
6230 }
6231 run_test 57a "verify MDS filesystem created with large inodes =="
6232
6233 test_57b() {
6234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6235         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6236                 skip_env "ldiskfs only test"
6237         fi
6238         remote_mds_nodsh && skip "remote MDS with nodsh"
6239
6240         local dir=$DIR/$tdir
6241         local filecount=100
6242         local file1=$dir/f1
6243         local fileN=$dir/f$filecount
6244
6245         rm -rf $dir || error "removing $dir"
6246         test_mkdir -c1 $dir
6247         local mdtidx=$($LFS getstripe -m $dir)
6248         local mdtname=MDT$(printf %04x $mdtidx)
6249         local facet=mds$((mdtidx + 1))
6250
6251         echo "mcreating $filecount files"
6252         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
6253
6254         # verify that files do not have EAs yet
6255         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
6256                 error "$file1 has an EA"
6257         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
6258                 error "$fileN has an EA"
6259
6260         sync
6261         sleep 1
6262         df $dir  #make sure we get new statfs data
6263         local mdsfree=$(do_facet $facet \
6264                         lctl get_param -n osd*.*$mdtname.kbytesfree)
6265         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6266         local file
6267
6268         echo "opening files to create objects/EAs"
6269         for file in $(seq -f $dir/f%g 1 $filecount); do
6270                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
6271                         error "opening $file"
6272         done
6273
6274         # verify that files have EAs now
6275         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
6276         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
6277
6278         sleep 1  #make sure we get new statfs data
6279         df $dir
6280         local mdsfree2=$(do_facet $facet \
6281                          lctl get_param -n osd*.*$mdtname.kbytesfree)
6282         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6283
6284         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
6285                 if [ "$mdsfree" != "$mdsfree2" ]; then
6286                         error "MDC before $mdcfree != after $mdcfree2"
6287                 else
6288                         echo "MDC before $mdcfree != after $mdcfree2"
6289                         echo "unable to confirm if MDS has large inodes"
6290                 fi
6291         fi
6292         rm -rf $dir
6293 }
6294 run_test 57b "default LOV EAs are stored inside large inodes ==="
6295
6296 test_58() {
6297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6298         [ -z "$(which wiretest 2>/dev/null)" ] &&
6299                         skip_env "could not find wiretest"
6300
6301         wiretest
6302 }
6303 run_test 58 "verify cross-platform wire constants =============="
6304
6305 test_59() {
6306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6307
6308         echo "touch 130 files"
6309         createmany -o $DIR/f59- 130
6310         echo "rm 130 files"
6311         unlinkmany $DIR/f59- 130
6312         sync
6313         # wait for commitment of removal
6314         wait_delete_completed
6315 }
6316 run_test 59 "verify cancellation of llog records async ========="
6317
6318 TEST60_HEAD="test_60 run $RANDOM"
6319 test_60a() {
6320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6321         remote_mgs_nodsh && skip "remote MGS with nodsh"
6322         do_facet mgs "! which run-llog.sh &> /dev/null" &&
6323                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
6324                         skip_env "missing subtest run-llog.sh"
6325
6326         log "$TEST60_HEAD - from kernel mode"
6327         do_facet mgs "$LCTL dk > /dev/null"
6328         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
6329         do_facet mgs $LCTL dk > $TMP/$tfile
6330
6331         # LU-6388: test llog_reader
6332         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
6333         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
6334         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
6335                         skip_env "missing llog_reader"
6336         local fstype=$(facet_fstype mgs)
6337         [ $fstype != ldiskfs -a $fstype != zfs ] &&
6338                 skip_env "Only for ldiskfs or zfs type mgs"
6339
6340         local mntpt=$(facet_mntpt mgs)
6341         local mgsdev=$(mgsdevname 1)
6342         local fid_list
6343         local fid
6344         local rec_list
6345         local rec
6346         local rec_type
6347         local obj_file
6348         local path
6349         local seq
6350         local oid
6351         local pass=true
6352
6353         #get fid and record list
6354         fid_list=($(awk '/9_sub.*record/ { print $NF }' /$TMP/$tfile |
6355                 tail -n 4))
6356         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' /$TMP/$tfile |
6357                 tail -n 4))
6358         #remount mgs as ldiskfs or zfs type
6359         stop mgs || error "stop mgs failed"
6360         mount_fstype mgs || error "remount mgs failed"
6361         for ((i = 0; i < ${#fid_list[@]}; i++)); do
6362                 fid=${fid_list[i]}
6363                 rec=${rec_list[i]}
6364                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
6365                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
6366                 oid=$((16#$oid))
6367
6368                 case $fstype in
6369                         ldiskfs )
6370                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
6371                         zfs )
6372                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
6373                 esac
6374                 echo "obj_file is $obj_file"
6375                 do_facet mgs $llog_reader $obj_file
6376
6377                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
6378                         awk '{ print $3 }' | sed -e "s/^type=//g")
6379                 if [ $rec_type != $rec ]; then
6380                         echo "FAILED test_60a wrong record type $rec_type," \
6381                               "should be $rec"
6382                         pass=false
6383                         break
6384                 fi
6385
6386                 #check obj path if record type is LLOG_LOGID_MAGIC
6387                 if [ "$rec" == "1064553b" ]; then
6388                         path=$(do_facet mgs $llog_reader $obj_file |
6389                                 grep "path=" | awk '{ print $NF }' |
6390                                 sed -e "s/^path=//g")
6391                         if [ $obj_file != $mntpt/$path ]; then
6392                                 echo "FAILED test_60a wrong obj path" \
6393                                       "$montpt/$path, should be $obj_file"
6394                                 pass=false
6395                                 break
6396                         fi
6397                 fi
6398         done
6399         rm -f $TMP/$tfile
6400         #restart mgs before "error", otherwise it will block the next test
6401         stop mgs || error "stop mgs failed"
6402         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
6403         $pass || error "test failed, see FAILED test_60a messages for specifics"
6404 }
6405 run_test 60a "llog_test run from kernel module and test llog_reader"
6406
6407 test_60b() { # bug 6411
6408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6409
6410         dmesg > $DIR/$tfile
6411         LLOG_COUNT=$(do_facet mgs dmesg |
6412                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
6413                           /llog_[a-z]*.c:[0-9]/ {
6414                                 if (marker)
6415                                         from_marker++
6416                                 from_begin++
6417                           }
6418                           END {
6419                                 if (marker)
6420                                         print from_marker
6421                                 else
6422                                         print from_begin
6423                           }")
6424
6425         [[ $LLOG_COUNT -gt 120 ]] &&
6426                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
6427 }
6428 run_test 60b "limit repeated messages from CERROR/CWARN"
6429
6430 test_60c() {
6431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6432
6433         echo "create 5000 files"
6434         createmany -o $DIR/f60c- 5000
6435 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
6436         lctl set_param fail_loc=0x80000137
6437         unlinkmany $DIR/f60c- 5000
6438         lctl set_param fail_loc=0
6439 }
6440 run_test 60c "unlink file when mds full"
6441
6442 test_60d() {
6443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6444
6445         SAVEPRINTK=$(lctl get_param -n printk)
6446         # verify "lctl mark" is even working"
6447         MESSAGE="test message ID $RANDOM $$"
6448         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6449         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
6450
6451         lctl set_param printk=0 || error "set lnet.printk failed"
6452         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
6453         MESSAGE="new test message ID $RANDOM $$"
6454         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
6455         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6456         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
6457
6458         lctl set_param -n printk="$SAVEPRINTK"
6459 }
6460 run_test 60d "test printk console message masking"
6461
6462 test_60e() {
6463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6464         remote_mds_nodsh && skip "remote MDS with nodsh"
6465
6466         touch $DIR/$tfile
6467 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
6468         do_facet mds1 lctl set_param fail_loc=0x15b
6469         rm $DIR/$tfile
6470 }
6471 run_test 60e "no space while new llog is being created"
6472
6473 test_60g() {
6474         local pid
6475
6476         test_mkdir -c $MDSCOUNT $DIR/$tdir
6477         $LFS setdirstripe -D -i -1 -c $MDSCOUNT $DIR/$tdir
6478
6479         (
6480                 local index=0
6481                 while true; do
6482                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
6483                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
6484                         index=$((index + 1))
6485                 done
6486         ) &
6487
6488         pid=$!
6489
6490         for i in $(seq 100); do 
6491                 # define OBD_FAIL_OSD_TXN_START    0x19a
6492                 do_facet mds1 lctl set_param fail_loc=0x8000019a
6493                 usleep 100
6494         done
6495
6496         kill -9 $pid
6497
6498         mkdir $DIR/$tdir/new || error "mkdir failed"
6499         rmdir $DIR/$tdir/new || error "rmdir failed"
6500 }
6501 run_test 60g "transaction abort won't cause MDT hung"
6502
6503 test_61a() {
6504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6505
6506         f="$DIR/f61"
6507         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
6508         cancel_lru_locks osc
6509         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
6510         sync
6511 }
6512 run_test 61a "mmap() writes don't make sync hang ================"
6513
6514 test_61b() {
6515         mmap_mknod_test $tfile || error "mmap_mknod_test failed"
6516 }
6517 run_test 61b "mmap() of unstriped file is successful"
6518
6519 # bug 2330 - insufficient obd_match error checking causes LBUG
6520 test_62() {
6521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6522
6523         f="$DIR/f62"
6524         echo foo > $f
6525         cancel_lru_locks osc
6526         lctl set_param fail_loc=0x405
6527         cat $f && error "cat succeeded, expect -EIO"
6528         lctl set_param fail_loc=0
6529 }
6530 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
6531 # match every page all of the time.
6532 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
6533
6534 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
6535 # Though this test is irrelevant anymore, it helped to reveal some
6536 # other grant bugs (LU-4482), let's keep it.
6537 test_63a() {   # was test_63
6538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6539
6540         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
6541
6542         for i in `seq 10` ; do
6543                 dd if=/dev/zero of=$DIR/f63 bs=8k &
6544                 sleep 5
6545                 kill $!
6546                 sleep 1
6547         done
6548
6549         rm -f $DIR/f63 || true
6550 }
6551 run_test 63a "Verify oig_wait interruption does not crash ======="
6552
6553 # bug 2248 - async write errors didn't return to application on sync
6554 # bug 3677 - async write errors left page locked
6555 test_63b() {
6556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6557
6558         debugsave
6559         lctl set_param debug=-1
6560
6561         # ensure we have a grant to do async writes
6562         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
6563         rm $DIR/$tfile
6564
6565         sync    # sync lest earlier test intercept the fail_loc
6566
6567         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
6568         lctl set_param fail_loc=0x80000406
6569         $MULTIOP $DIR/$tfile Owy && \
6570                 error "sync didn't return ENOMEM"
6571         sync; sleep 2; sync     # do a real sync this time to flush page
6572         lctl get_param -n llite.*.dump_page_cache | grep locked && \
6573                 error "locked page left in cache after async error" || true
6574         debugrestore
6575 }
6576 run_test 63b "async write errors should be returned to fsync ==="
6577
6578 test_64a () {
6579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6580
6581         df $DIR
6582         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
6583 }
6584 run_test 64a "verify filter grant calculations (in kernel) ====="
6585
6586 test_64b () {
6587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6588
6589         sh oos.sh $MOUNT || error "oos.sh failed: $?"
6590 }
6591 run_test 64b "check out-of-space detection on client"
6592
6593 test_64c() {
6594         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
6595 }
6596 run_test 64c "verify grant shrink"
6597
6598 # this does exactly what osc_request.c:osc_announce_cached() does in
6599 # order to calculate max amount of grants to ask from server
6600 want_grant() {
6601         local tgt=$1
6602
6603         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
6604         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
6605
6606         ((rpc_in_flight ++));
6607         nrpages=$((nrpages * rpc_in_flight))
6608
6609         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
6610
6611         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
6612
6613         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
6614         local undirty=$((nrpages * PAGE_SIZE))
6615
6616         local max_extent_pages
6617         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
6618             grep grant_max_extent_size | awk '{print $2}')
6619         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
6620         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
6621         local grant_extent_tax
6622         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
6623             grep grant_extent_tax | awk '{print $2}')
6624
6625         undirty=$((undirty + nrextents * grant_extent_tax))
6626
6627         echo $undirty
6628 }
6629
6630 # this is size of unit for grant allocation. It should be equal to
6631 # what tgt_grant.c:tgt_grant_chunk() calculates
6632 grant_chunk() {
6633         local tgt=$1
6634         local max_brw_size
6635         local grant_extent_tax
6636
6637         max_brw_size=$($LCTL get_param osc.${tgt}.import |
6638             grep max_brw_size | awk '{print $2}')
6639
6640         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
6641             grep grant_extent_tax | awk '{print $2}')
6642
6643         echo $(((max_brw_size + grant_extent_tax) * 2))
6644 }
6645
6646 test_64d() {
6647         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
6648                 skip "OST < 2.10.55 doesn't limit grants enough"
6649
6650         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
6651         local file=$DIR/$tfile
6652
6653         [[ $($LCTL get_param osc.${tgt}.import |
6654              grep "connect_flags:.*grant_param") ]] ||
6655                 skip "no grant_param connect flag"
6656
6657         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
6658
6659         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
6660
6661         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
6662         stack_trap "rm -f $file" EXIT
6663
6664         $LFS setstripe $file -i 0 -c 1
6665         dd if=/dev/zero of=$file bs=1M count=1000 &
6666         ddpid=$!
6667
6668         while true
6669         do
6670                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
6671                 if [[ $cur_grant -gt $max_cur_granted ]]
6672                 then
6673                         kill $ddpid
6674                         error "cur_grant $cur_grant > $max_cur_granted"
6675                 fi
6676                 kill -0 $ddpid
6677                 [[ $? -ne 0 ]] && break;
6678                 sleep 2
6679         done
6680
6681         rm -f $DIR/$tfile
6682         wait_delete_completed
6683         $LCTL set_param debug="$olddebug" 2> /dev/null || true
6684 }
6685 run_test 64d "check grant limit exceed"
6686
6687 # bug 1414 - set/get directories' stripe info
6688 test_65a() {
6689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6690
6691         test_mkdir $DIR/$tdir
6692         touch $DIR/$tdir/f1
6693         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
6694 }
6695 run_test 65a "directory with no stripe info"
6696
6697 test_65b() {
6698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6699
6700         test_mkdir $DIR/$tdir
6701         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6702
6703         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6704                                                 error "setstripe"
6705         touch $DIR/$tdir/f2
6706         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
6707 }
6708 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
6709
6710 test_65c() {
6711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6712         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
6713
6714         test_mkdir $DIR/$tdir
6715         local stripesize=$($LFS getstripe -S $DIR/$tdir)
6716
6717         $LFS setstripe -S $((stripesize * 4)) -i 1 \
6718                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
6719         touch $DIR/$tdir/f3
6720         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
6721 }
6722 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
6723
6724 test_65d() {
6725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6726
6727         test_mkdir $DIR/$tdir
6728         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
6729         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6730
6731         if [[ $STRIPECOUNT -le 0 ]]; then
6732                 sc=1
6733         elif [[ $STRIPECOUNT -gt 2000 ]]; then
6734 #LOV_MAX_STRIPE_COUNT is 2000
6735                 [[ $OSTCOUNT -gt 2000 ]] && sc=2000 || sc=$(($OSTCOUNT - 1))
6736         else
6737                 sc=$(($STRIPECOUNT - 1))
6738         fi
6739         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
6740         touch $DIR/$tdir/f4 $DIR/$tdir/f5
6741         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
6742                 error "lverify failed"
6743 }
6744 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
6745
6746 test_65e() {
6747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6748
6749         test_mkdir $DIR/$tdir
6750
6751         $LFS setstripe $DIR/$tdir || error "setstripe"
6752         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
6753                                         error "no stripe info failed"
6754         touch $DIR/$tdir/f6
6755         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
6756 }
6757 run_test 65e "directory setstripe defaults"
6758
6759 test_65f() {
6760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6761
6762         test_mkdir $DIR/${tdir}f
6763         $RUNAS $LFS setstripe $DIR/${tdir}f &&
6764                 error "setstripe succeeded" || true
6765 }
6766 run_test 65f "dir setstripe permission (should return error) ==="
6767
6768 test_65g() {
6769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6770
6771         test_mkdir $DIR/$tdir
6772         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6773
6774         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6775                 error "setstripe -S failed"
6776         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
6777         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
6778                 error "delete default stripe failed"
6779 }
6780 run_test 65g "directory setstripe -d"
6781
6782 test_65h() {
6783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6784
6785         test_mkdir $DIR/$tdir
6786         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6787
6788         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6789                 error "setstripe -S failed"
6790         test_mkdir $DIR/$tdir/dd1
6791         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
6792                 error "stripe info inherit failed"
6793 }
6794 run_test 65h "directory stripe info inherit ===================="
6795
6796 test_65i() {
6797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6798
6799         save_layout_restore_at_exit $MOUNT
6800
6801         # bug6367: set non-default striping on root directory
6802         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
6803
6804         # bug12836: getstripe on -1 default directory striping
6805         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
6806
6807         # bug12836: getstripe -v on -1 default directory striping
6808         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
6809
6810         # bug12836: new find on -1 default directory striping
6811         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
6812 }
6813 run_test 65i "various tests to set root directory striping"
6814
6815 test_65j() { # bug6367
6816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6817
6818         sync; sleep 1
6819
6820         # if we aren't already remounting for each test, do so for this test
6821         if [ "$CLEANUP" = ":" -a "$I_MOUNTED" = "yes" ]; then
6822                 cleanup || error "failed to unmount"
6823                 setup
6824         fi
6825
6826         save_layout_restore_at_exit $MOUNT
6827
6828         $LFS setstripe -d $MOUNT || error "setstripe failed"
6829 }
6830 run_test 65j "set default striping on root directory (bug 6367)="
6831
6832 cleanup_65k() {
6833         rm -rf $DIR/$tdir
6834         wait_delete_completed
6835         do_facet $SINGLEMDS "lctl set_param -n \
6836                 osp.$ost*MDT0000.max_create_count=$max_count"
6837         do_facet $SINGLEMDS "lctl set_param -n \
6838                 osp.$ost*MDT0000.create_count=$count"
6839         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
6840         echo $INACTIVE_OSC "is Activate"
6841
6842         wait_osc_import_state mds ost$ostnum FULL
6843 }
6844
6845 test_65k() { # bug11679
6846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6847         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6848         remote_mds_nodsh && skip "remote MDS with nodsh"
6849
6850         local disable_precreate=true
6851         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
6852                 disable_precreate=false
6853
6854         echo "Check OST status: "
6855         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
6856                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
6857
6858         for OSC in $MDS_OSCS; do
6859                 echo $OSC "is active"
6860                 do_facet $SINGLEMDS lctl --device %$OSC activate
6861         done
6862
6863         for INACTIVE_OSC in $MDS_OSCS; do
6864                 local ost=$(osc_to_ost $INACTIVE_OSC)
6865                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
6866                                lov.*md*.target_obd |
6867                                awk -F: /$ost/'{ print $1 }' | head -n 1)
6868
6869                 mkdir -p $DIR/$tdir
6870                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
6871                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
6872
6873                 echo "Deactivate: " $INACTIVE_OSC
6874                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
6875
6876                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
6877                               osp.$ost*MDT0000.create_count")
6878                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
6879                                   osp.$ost*MDT0000.max_create_count")
6880                 $disable_precreate &&
6881                         do_facet $SINGLEMDS "lctl set_param -n \
6882                                 osp.$ost*MDT0000.max_create_count=0"
6883
6884                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
6885                         [ -f $DIR/$tdir/$idx ] && continue
6886                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
6887                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
6888                                 { cleanup_65k;
6889                                   error "setstripe $idx should succeed"; }
6890                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
6891                 done
6892                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
6893                 rmdir $DIR/$tdir
6894
6895                 do_facet $SINGLEMDS "lctl set_param -n \
6896                         osp.$ost*MDT0000.max_create_count=$max_count"
6897                 do_facet $SINGLEMDS "lctl set_param -n \
6898                         osp.$ost*MDT0000.create_count=$count"
6899                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
6900                 echo $INACTIVE_OSC "is Activate"
6901
6902                 wait_osc_import_state mds ost$ostnum FULL
6903         done
6904 }
6905 run_test 65k "validate manual striping works properly with deactivated OSCs"
6906
6907 test_65l() { # bug 12836
6908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6909
6910         test_mkdir -p $DIR/$tdir/test_dir
6911         $LFS setstripe -c -1 $DIR/$tdir/test_dir
6912         $LFS find -mtime -1 $DIR/$tdir >/dev/null
6913 }
6914 run_test 65l "lfs find on -1 stripe dir ========================"
6915
6916 test_65m() {
6917         local layout=$(save_layout $MOUNT)
6918         $RUNAS $LFS setstripe -c 2 $MOUNT && {
6919                 restore_layout $MOUNT $layout
6920                 error "setstripe should fail by non-root users"
6921         }
6922         true
6923 }
6924 run_test 65m "normal user can't set filesystem default stripe"
6925
6926 test_65n() {
6927         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
6928         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.12.50) ]] ||
6929                 skip "Need MDS version at least 2.12.50"
6930         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
6931
6932         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
6933         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
6934         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
6935
6936         local root_layout=$(save_layout $MOUNT)
6937         stack_trap "restore_layout $MOUNT $root_layout" EXIT
6938
6939         # new subdirectory under root directory should not inherit
6940         # the default layout from root
6941         local dir1=$MOUNT/$tdir-1
6942         mkdir $dir1 || error "mkdir $dir1 failed"
6943         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
6944                 error "$dir1 shouldn't have LOV EA"
6945
6946         # delete the default layout on root directory
6947         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
6948
6949         local dir2=$MOUNT/$tdir-2
6950         mkdir $dir2 || error "mkdir $dir2 failed"
6951         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
6952                 error "$dir2 shouldn't have LOV EA"
6953
6954         # set a new striping pattern on root directory
6955         local def_stripe_size=$($LFS getstripe -S $MOUNT)
6956         local new_def_stripe_size=$((def_stripe_size * 2))
6957         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
6958                 error "set stripe size on $MOUNT failed"
6959
6960         # new file created in $dir2 should inherit the new stripe size from
6961         # the filesystem default
6962         local file2=$dir2/$tfile-2
6963         touch $file2 || error "touch $file2 failed"
6964
6965         local file2_stripe_size=$($LFS getstripe -S $file2)
6966         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
6967                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
6968
6969         local dir3=$MOUNT/$tdir-3
6970         mkdir $dir3 || error "mkdir $dir3 failed"
6971         ! getfattr -n trusted.lov $dir3 &> /dev/null ||
6972                 error "$dir3 shouldn't have LOV EA"
6973
6974         # set OST pool on root directory
6975         local pool=$TESTNAME
6976         pool_add $pool || error "add $pool failed"
6977         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
6978                 error "add targets to $pool failed"
6979
6980         $LFS setstripe -p $pool $MOUNT ||
6981                 error "set OST pool on $MOUNT failed"
6982
6983         # new file created in $dir3 should inherit the pool from
6984         # the filesystem default
6985         local file3=$dir3/$tfile-3
6986         touch $file3 || error "touch $file3 failed"
6987
6988         local file3_pool=$($LFS getstripe -p $file3)
6989         [[ "$file3_pool" = "$pool" ]] ||
6990                 error "$file3 didn't inherit OST pool $pool"
6991
6992         local dir4=$MOUNT/$tdir-4
6993         mkdir $dir4 || error "mkdir $dir4 failed"
6994         ! getfattr -n trusted.lov $dir4 &> /dev/null ||
6995                 error "$dir4 shouldn't have LOV EA"
6996
6997         # new file created in $dir4 should inherit the pool from
6998         # the filesystem default
6999         local file4=$dir4/$tfile-4
7000         touch $file4 || error "touch $file4 failed"
7001
7002         local file4_pool=$($LFS getstripe -p $file4)
7003         [[ "$file4_pool" = "$pool" ]] ||
7004                 error "$file4 didn't inherit OST pool $pool"
7005
7006         # new subdirectory under non-root directory should inherit
7007         # the default layout from its parent directory
7008         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
7009                 error "set directory layout on $dir4 failed"
7010
7011         local dir5=$dir4/$tdir-5
7012         mkdir $dir5 || error "mkdir $dir5 failed"
7013
7014         local dir4_layout=$(get_layout_param $dir4)
7015         local dir5_layout=$(get_layout_param $dir5)
7016         [[ "$dir4_layout" = "$dir5_layout" ]] ||
7017                 error "$dir5 should inherit the default layout from $dir4"
7018 }
7019 run_test 65n "don't inherit default layout from root for new subdirectories"
7020
7021 # bug 2543 - update blocks count on client
7022 test_66() {
7023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7024
7025         COUNT=${COUNT:-8}
7026         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
7027         sync; sync_all_data; sync; sync_all_data
7028         cancel_lru_locks osc
7029         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
7030         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
7031 }
7032 run_test 66 "update inode blocks count on client ==============="
7033
7034 meminfo() {
7035         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
7036 }
7037
7038 swap_used() {
7039         swapon -s | awk '($1 == "'$1'") { print $4 }'
7040 }
7041
7042 # bug5265, obdfilter oa2dentry return -ENOENT
7043 # #define OBD_FAIL_SRV_ENOENT 0x217
7044 test_69() {
7045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7046         remote_ost_nodsh && skip "remote OST with nodsh"
7047
7048         f="$DIR/$tfile"
7049         $LFS setstripe -c 1 -i 0 $f
7050
7051         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
7052
7053         do_facet ost1 lctl set_param fail_loc=0x217
7054         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
7055         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
7056
7057         do_facet ost1 lctl set_param fail_loc=0
7058         $DIRECTIO write $f 0 2 || error "write error"
7059
7060         cancel_lru_locks osc
7061         $DIRECTIO read $f 0 1 || error "read error"
7062
7063         do_facet ost1 lctl set_param fail_loc=0x217
7064         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
7065
7066         do_facet ost1 lctl set_param fail_loc=0
7067         rm -f $f
7068 }
7069 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
7070
7071 test_71() {
7072         test_mkdir $DIR/$tdir
7073         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
7074         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
7075 }
7076 run_test 71 "Running dbench on lustre (don't segment fault) ===="
7077
7078 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
7079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7080         [ "$RUNAS_ID" = "$UID" ] &&
7081                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7082         # Check that testing environment is properly set up. Skip if not
7083         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
7084                 skip_env "User $RUNAS_ID does not exist - skipping"
7085
7086         touch $DIR/$tfile
7087         chmod 777 $DIR/$tfile
7088         chmod ug+s $DIR/$tfile
7089         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
7090                 error "$RUNAS dd $DIR/$tfile failed"
7091         # See if we are still setuid/sgid
7092         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7093                 error "S/gid is not dropped on write"
7094         # Now test that MDS is updated too
7095         cancel_lru_locks mdc
7096         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7097                 error "S/gid is not dropped on MDS"
7098         rm -f $DIR/$tfile
7099 }
7100 run_test 72a "Test that remove suid works properly (bug5695) ===="
7101
7102 test_72b() { # bug 24226 -- keep mode setting when size is not changing
7103         local perm
7104
7105         [ "$RUNAS_ID" = "$UID" ] &&
7106                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7107         [ "$RUNAS_ID" -eq 0 ] &&
7108                 skip_env "RUNAS_ID = 0 -- skipping"
7109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7110         # Check that testing environment is properly set up. Skip if not
7111         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
7112                 skip_env "User $RUNAS_ID does not exist - skipping"
7113
7114         touch $DIR/${tfile}-f{g,u}
7115         test_mkdir $DIR/${tfile}-dg
7116         test_mkdir $DIR/${tfile}-du
7117         chmod 770 $DIR/${tfile}-{f,d}{g,u}
7118         chmod g+s $DIR/${tfile}-{f,d}g
7119         chmod u+s $DIR/${tfile}-{f,d}u
7120         for perm in 777 2777 4777; do
7121                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
7122                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
7123                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
7124                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
7125         done
7126         true
7127 }
7128 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
7129
7130 # bug 3462 - multiple simultaneous MDC requests
7131 test_73() {
7132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7133
7134         test_mkdir $DIR/d73-1
7135         test_mkdir $DIR/d73-2
7136         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
7137         pid1=$!
7138
7139         lctl set_param fail_loc=0x80000129
7140         $MULTIOP $DIR/d73-1/f73-2 Oc &
7141         sleep 1
7142         lctl set_param fail_loc=0
7143
7144         $MULTIOP $DIR/d73-2/f73-3 Oc &
7145         pid3=$!
7146
7147         kill -USR1 $pid1
7148         wait $pid1 || return 1
7149
7150         sleep 25
7151
7152         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
7153         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
7154         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
7155
7156         rm -rf $DIR/d73-*
7157 }
7158 run_test 73 "multiple MDC requests (should not deadlock)"
7159
7160 test_74a() { # bug 6149, 6184
7161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7162
7163         touch $DIR/f74a
7164         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7165         #
7166         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7167         # will spin in a tight reconnection loop
7168         $LCTL set_param fail_loc=0x8000030e
7169         # get any lock that won't be difficult - lookup works.
7170         ls $DIR/f74a
7171         $LCTL set_param fail_loc=0
7172         rm -f $DIR/f74a
7173         true
7174 }
7175 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
7176
7177 test_74b() { # bug 13310
7178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7179
7180         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7181         #
7182         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7183         # will spin in a tight reconnection loop
7184         $LCTL set_param fail_loc=0x8000030e
7185         # get a "difficult" lock
7186         touch $DIR/f74b
7187         $LCTL set_param fail_loc=0
7188         rm -f $DIR/f74b
7189         true
7190 }
7191 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
7192
7193 test_74c() {
7194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7195
7196         #define OBD_FAIL_LDLM_NEW_LOCK
7197         $LCTL set_param fail_loc=0x319
7198         touch $DIR/$tfile && error "touch successful"
7199         $LCTL set_param fail_loc=0
7200         true
7201 }
7202 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
7203
7204 num_inodes() {
7205         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
7206 }
7207
7208 test_76() { # Now for bug 20433, added originally in bug 1443
7209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7210
7211         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
7212
7213         cancel_lru_locks osc
7214         BEFORE_INODES=$(num_inodes)
7215         echo "before inodes: $BEFORE_INODES"
7216         local COUNT=1000
7217         [ "$SLOW" = "no" ] && COUNT=100
7218         for i in $(seq $COUNT); do
7219                 touch $DIR/$tfile
7220                 rm -f $DIR/$tfile
7221         done
7222         cancel_lru_locks osc
7223         AFTER_INODES=$(num_inodes)
7224         echo "after inodes: $AFTER_INODES"
7225         local wait=0
7226         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
7227                 sleep 2
7228                 AFTER_INODES=$(num_inodes)
7229                 wait=$((wait+2))
7230                 echo "wait $wait seconds inodes: $AFTER_INODES"
7231                 if [ $wait -gt 30 ]; then
7232                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
7233                 fi
7234         done
7235 }
7236 run_test 76 "confirm clients recycle inodes properly ===="
7237
7238
7239 export ORIG_CSUM=""
7240 set_checksums()
7241 {
7242         # Note: in sptlrpc modes which enable its own bulk checksum, the
7243         # original crc32_le bulk checksum will be automatically disabled,
7244         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
7245         # will be checked by sptlrpc code against sptlrpc bulk checksum.
7246         # In this case set_checksums() will not be no-op, because sptlrpc
7247         # bulk checksum will be enabled all through the test.
7248
7249         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
7250         lctl set_param -n osc.*.checksums $1
7251         return 0
7252 }
7253
7254 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7255                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
7256 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7257                              tr -d [] | head -n1)}
7258 set_checksum_type()
7259 {
7260         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
7261         log "set checksum type to $1"
7262         return 0
7263 }
7264 F77_TMP=$TMP/f77-temp
7265 F77SZ=8
7266 setup_f77() {
7267         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
7268                 error "error writing to $F77_TMP"
7269 }
7270
7271 test_77a() { # bug 10889
7272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7273         $GSS && skip_env "could not run with gss"
7274
7275         [ ! -f $F77_TMP ] && setup_f77
7276         set_checksums 1
7277         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
7278         set_checksums 0
7279         rm -f $DIR/$tfile
7280 }
7281 run_test 77a "normal checksum read/write operation"
7282
7283 test_77b() { # bug 10889
7284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7285         $GSS && skip_env "could not run with gss"
7286
7287         [ ! -f $F77_TMP ] && setup_f77
7288         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7289         $LCTL set_param fail_loc=0x80000409
7290         set_checksums 1
7291
7292         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7293                 error "dd error: $?"
7294         $LCTL set_param fail_loc=0
7295
7296         for algo in $CKSUM_TYPES; do
7297                 cancel_lru_locks osc
7298                 set_checksum_type $algo
7299                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7300                 $LCTL set_param fail_loc=0x80000408
7301                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
7302                 $LCTL set_param fail_loc=0
7303         done
7304         set_checksums 0
7305         set_checksum_type $ORIG_CSUM_TYPE
7306         rm -f $DIR/$tfile
7307 }
7308 run_test 77b "checksum error on client write, read"
7309
7310 cleanup_77c() {
7311         trap 0
7312         set_checksums 0
7313         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
7314         $check_ost &&
7315                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
7316         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
7317         $check_ost && [ -n "$ost_file_prefix" ] &&
7318                 do_facet ost1 rm -f ${ost_file_prefix}\*
7319 }
7320
7321 test_77c() {
7322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7323         $GSS && skip_env "could not run with gss"
7324         remote_ost_nodsh && skip "remote OST with nodsh"
7325
7326         local bad1
7327         local osc_file_prefix
7328         local osc_file
7329         local check_ost=false
7330         local ost_file_prefix
7331         local ost_file
7332         local orig_cksum
7333         local dump_cksum
7334         local fid
7335
7336         # ensure corruption will occur on first OSS/OST
7337         $LFS setstripe -i 0 $DIR/$tfile
7338
7339         [ ! -f $F77_TMP ] && setup_f77
7340         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7341                 error "dd write error: $?"
7342         fid=$($LFS path2fid $DIR/$tfile)
7343
7344         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
7345         then
7346                 check_ost=true
7347                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
7348                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
7349         else
7350                 echo "OSS do not support bulk pages dump upon error"
7351         fi
7352
7353         osc_file_prefix=$($LCTL get_param -n debug_path)
7354         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
7355
7356         trap cleanup_77c EXIT
7357
7358         set_checksums 1
7359         # enable bulk pages dump upon error on Client
7360         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
7361         # enable bulk pages dump upon error on OSS
7362         $check_ost &&
7363                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
7364
7365         # flush Client cache to allow next read to reach OSS
7366         cancel_lru_locks osc
7367
7368         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
7369         $LCTL set_param fail_loc=0x80000408
7370         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
7371         $LCTL set_param fail_loc=0
7372
7373         rm -f $DIR/$tfile
7374
7375         # check cksum dump on Client
7376         osc_file=$(ls ${osc_file_prefix}*)
7377         [ -n "$osc_file" ] || error "no checksum dump file on Client"
7378         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
7379         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
7380         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
7381         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
7382                      cksum)
7383         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
7384         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7385                 error "dump content does not match on Client"
7386
7387         $check_ost || skip "No need to check cksum dump on OSS"
7388
7389         # check cksum dump on OSS
7390         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
7391         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
7392         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
7393         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
7394         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7395                 error "dump content does not match on OSS"
7396
7397         cleanup_77c
7398 }
7399 run_test 77c "checksum error on client read with debug"
7400
7401 test_77d() { # bug 10889
7402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7403         $GSS && skip_env "could not run with gss"
7404
7405         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7406         $LCTL set_param fail_loc=0x80000409
7407         set_checksums 1
7408         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7409                 error "direct write: rc=$?"
7410         $LCTL set_param fail_loc=0
7411         set_checksums 0
7412
7413         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7414         $LCTL set_param fail_loc=0x80000408
7415         set_checksums 1
7416         cancel_lru_locks osc
7417         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7418                 error "direct read: rc=$?"
7419         $LCTL set_param fail_loc=0
7420         set_checksums 0
7421 }
7422 run_test 77d "checksum error on OST direct write, read"
7423
7424 test_77f() { # bug 10889
7425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7426         $GSS && skip_env "could not run with gss"
7427
7428         set_checksums 1
7429         for algo in $CKSUM_TYPES; do
7430                 cancel_lru_locks osc
7431                 set_checksum_type $algo
7432                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7433                 $LCTL set_param fail_loc=0x409
7434                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
7435                         error "direct write succeeded"
7436                 $LCTL set_param fail_loc=0
7437         done
7438         set_checksum_type $ORIG_CSUM_TYPE
7439         set_checksums 0
7440 }
7441 run_test 77f "repeat checksum error on write (expect error)"
7442
7443 test_77g() { # bug 10889
7444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7445         $GSS && skip_env "could not run with gss"
7446         remote_ost_nodsh && skip "remote OST with nodsh"
7447
7448         [ ! -f $F77_TMP ] && setup_f77
7449
7450         local file=$DIR/$tfile
7451         stack_trap "rm -f $file" EXIT
7452
7453         $LFS setstripe -c 1 -i 0 $file
7454         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
7455         do_facet ost1 lctl set_param fail_loc=0x8000021a
7456         set_checksums 1
7457         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
7458                 error "write error: rc=$?"
7459         do_facet ost1 lctl set_param fail_loc=0
7460         set_checksums 0
7461
7462         cancel_lru_locks osc
7463         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
7464         do_facet ost1 lctl set_param fail_loc=0x8000021b
7465         set_checksums 1
7466         cmp $F77_TMP $file || error "file compare failed"
7467         do_facet ost1 lctl set_param fail_loc=0
7468         set_checksums 0
7469 }
7470 run_test 77g "checksum error on OST write, read"
7471
7472 test_77k() { # LU-10906
7473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7474         $GSS && skip_env "could not run with gss"
7475
7476         local cksum_param="osc.$FSNAME*.checksums"
7477         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
7478         local checksum
7479         local i
7480
7481         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
7482         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
7483         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
7484                 EXIT
7485
7486         for i in 0 1; do
7487                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
7488                         error "failed to set checksum=$i on MGS"
7489                 wait_update $HOSTNAME "$get_checksum" $i
7490                 #remount
7491                 echo "remount client, checksum should be $i"
7492                 remount_client $MOUNT || "failed to remount client"
7493                 checksum=$(eval $get_checksum)
7494                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7495         done
7496         # remove persistent param to avoid races with checksum mountopt below
7497         do_facet mgs $LCTL set_param -P -d $cksum_param ||
7498                 error "failed to delete checksum on MGS"
7499
7500         for opt in "checksum" "nochecksum"; do
7501                 #remount with mount option
7502                 echo "remount client with option $opt, checksum should be $i"
7503                 umount_client $MOUNT || "failed to umount client"
7504                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
7505                         "failed to mount client with option '$opt'"
7506                 checksum=$(eval $get_checksum)
7507                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7508                 i=$((i - 1))
7509         done
7510
7511         remount_client $MOUNT || "failed to remount client"
7512 }
7513 run_test 77k "enable/disable checksum correctly"
7514
7515 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
7516 rm -f $F77_TMP
7517 unset F77_TMP
7518
7519 cleanup_test_78() {
7520         trap 0
7521         rm -f $DIR/$tfile
7522 }
7523
7524 test_78() { # bug 10901
7525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7526         remote_ost || skip_env "local OST"
7527
7528         NSEQ=5
7529         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
7530         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
7531         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
7532         echo "MemTotal: $MEMTOTAL"
7533
7534         # reserve 256MB of memory for the kernel and other running processes,
7535         # and then take 1/2 of the remaining memory for the read/write buffers.
7536         if [ $MEMTOTAL -gt 512 ] ;then
7537                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
7538         else
7539                 # for those poor memory-starved high-end clusters...
7540                 MEMTOTAL=$((MEMTOTAL / 2))
7541         fi
7542         echo "Mem to use for directio: $MEMTOTAL"
7543
7544         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
7545         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
7546         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
7547         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
7548                 head -n1)
7549         echo "Smallest OST: $SMALLESTOST"
7550         [[ $SMALLESTOST -lt 10240 ]] &&
7551                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
7552
7553         trap cleanup_test_78 EXIT
7554
7555         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
7556                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
7557
7558         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
7559         echo "File size: $F78SIZE"
7560         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
7561         for i in $(seq 1 $NSEQ); do
7562                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
7563                 echo directIO rdwr round $i of $NSEQ
7564                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
7565         done
7566
7567         cleanup_test_78
7568 }
7569 run_test 78 "handle large O_DIRECT writes correctly ============"
7570
7571 test_79() { # bug 12743
7572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7573
7574         wait_delete_completed
7575
7576         BKTOTAL=$(calc_osc_kbytes kbytestotal)
7577         BKFREE=$(calc_osc_kbytes kbytesfree)
7578         BKAVAIL=$(calc_osc_kbytes kbytesavail)
7579
7580         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
7581         DFTOTAL=`echo $STRING | cut -d, -f1`
7582         DFUSED=`echo $STRING  | cut -d, -f2`
7583         DFAVAIL=`echo $STRING | cut -d, -f3`
7584         DFFREE=$(($DFTOTAL - $DFUSED))
7585
7586         ALLOWANCE=$((64 * $OSTCOUNT))
7587
7588         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
7589            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
7590                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
7591         fi
7592         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
7593            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
7594                 error "df free($DFFREE) mismatch OST free($BKFREE)"
7595         fi
7596         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
7597            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
7598                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
7599         fi
7600 }
7601 run_test 79 "df report consistency check ======================="
7602
7603 test_80() { # bug 10718
7604         remote_ost_nodsh && skip "remote OST with nodsh"
7605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7606
7607         # relax strong synchronous semantics for slow backends like ZFS
7608         local soc="obdfilter.*.sync_on_lock_cancel"
7609         local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
7610         local hosts=
7611         if [ "$soc_old" != "never" ] &&
7612                 [ "$ost1_FSTYPE" != "ldiskfs" ]; then
7613                         hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
7614                                 facet_active_host $host; done | sort -u)
7615                         do_nodes $hosts lctl set_param $soc=never
7616         fi
7617
7618         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
7619         sync; sleep 1; sync
7620         local BEFORE=`date +%s`
7621         cancel_lru_locks osc
7622         local AFTER=`date +%s`
7623         local DIFF=$((AFTER-BEFORE))
7624         if [ $DIFF -gt 1 ] ; then
7625                 error "elapsed for 1M@1T = $DIFF"
7626         fi
7627
7628         [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
7629
7630         rm -f $DIR/$tfile
7631 }
7632 run_test 80 "Page eviction is equally fast at high offsets too  ===="
7633
7634 test_81a() { # LU-456
7635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7636         remote_ost_nodsh && skip "remote OST with nodsh"
7637
7638         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
7639         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
7640         do_facet ost1 lctl set_param fail_loc=0x80000228
7641
7642         # write should trigger a retry and success
7643         $LFS setstripe -i 0 -c 1 $DIR/$tfile
7644         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
7645         RC=$?
7646         if [ $RC -ne 0 ] ; then
7647                 error "write should success, but failed for $RC"
7648         fi
7649 }
7650 run_test 81a "OST should retry write when get -ENOSPC ==============="
7651
7652 test_81b() { # LU-456
7653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7654         remote_ost_nodsh && skip "remote OST with nodsh"
7655
7656         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
7657         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
7658         do_facet ost1 lctl set_param fail_loc=0x228
7659
7660         # write should retry several times and return -ENOSPC finally
7661         $LFS setstripe -i 0 -c 1 $DIR/$tfile
7662         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
7663         RC=$?
7664         ENOSPC=28
7665         if [ $RC -ne $ENOSPC ] ; then
7666                 error "dd should fail for -ENOSPC, but succeed."
7667         fi
7668 }
7669 run_test 81b "OST should return -ENOSPC when retry still fails ======="
7670
7671 test_82() { # LU-1031
7672         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
7673         local gid1=14091995
7674         local gid2=16022000
7675
7676         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
7677         local MULTIPID1=$!
7678         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
7679         local MULTIPID2=$!
7680         kill -USR1 $MULTIPID2
7681         sleep 2
7682         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
7683                 error "First grouplock does not block second one"
7684         else
7685                 echo "Second grouplock blocks first one"
7686         fi
7687         kill -USR1 $MULTIPID1
7688         wait $MULTIPID1
7689         wait $MULTIPID2
7690 }
7691 run_test 82 "Basic grouplock test"
7692
7693 test_99() {
7694         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
7695
7696         test_mkdir $DIR/$tdir.cvsroot
7697         chown $RUNAS_ID $DIR/$tdir.cvsroot
7698
7699         cd $TMP
7700         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
7701
7702         cd /etc/init.d
7703         # some versions of cvs import exit(1) when asked to import links or
7704         # files they can't read.  ignore those files.
7705         local toignore=$(find . -type l -printf '-I %f\n' -o \
7706                          ! -perm /4 -printf '-I %f\n')
7707         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
7708                 $tdir.reposname vtag rtag
7709
7710         cd $DIR
7711         test_mkdir $DIR/$tdir.reposname
7712         chown $RUNAS_ID $DIR/$tdir.reposname
7713         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
7714
7715         cd $DIR/$tdir.reposname
7716         $RUNAS touch foo99
7717         $RUNAS cvs add -m 'addmsg' foo99
7718         $RUNAS cvs update
7719         $RUNAS cvs commit -m 'nomsg' foo99
7720         rm -fr $DIR/$tdir.cvsroot
7721 }
7722 run_test 99 "cvs strange file/directory operations"
7723
7724 test_100() {
7725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7726         [[ "$NETTYPE" =~ tcp ]] ||
7727                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
7728         remote_ost_nodsh && skip "remote OST with nodsh"
7729         remote_mds_nodsh && skip "remote MDS with nodsh"
7730         remote_servers ||
7731                 skip "useless for local single node setup"
7732
7733         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
7734                 [ "$PROT" != "tcp" ] && continue
7735                 RPORT=$(echo $REMOTE | cut -d: -f2)
7736                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
7737
7738                 rc=0
7739                 LPORT=`echo $LOCAL | cut -d: -f2`
7740                 if [ $LPORT -ge 1024 ]; then
7741                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
7742                         netstat -tna
7743                         error_exit "local: $LPORT > 1024, remote: $RPORT"
7744                 fi
7745         done
7746         [ "$rc" = 0 ] || error_exit "privileged port not found" )
7747 }
7748 run_test 100 "check local port using privileged port ==========="
7749
7750 function get_named_value()
7751 {
7752     local tag
7753
7754     tag=$1
7755     while read ;do
7756         line=$REPLY
7757         case $line in
7758         $tag*)
7759             echo $line | sed "s/^$tag[ ]*//"
7760             break
7761             ;;
7762         esac
7763     done
7764 }
7765
7766 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
7767                    awk '/^max_cached_mb/ { print $2 }')
7768
7769 cleanup_101a() {
7770         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
7771         trap 0
7772 }
7773
7774 test_101a() {
7775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7776         [ $MDSCOUNT -ge 2 ] && skip_env "needs < 2 MDTs" #LU-4322
7777
7778         local s
7779         local discard
7780         local nreads=10000
7781         local cache_limit=32
7782
7783         $LCTL set_param -n osc.*-osc*.rpc_stats 0
7784         trap cleanup_101a EXIT
7785         $LCTL set_param -n llite.*.read_ahead_stats 0
7786         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
7787
7788         #
7789         # randomly read 10000 of 64K chunks from file 3x 32MB in size
7790         #
7791         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
7792         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
7793
7794         discard=0
7795         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
7796                 get_named_value 'read but discarded' | cut -d" " -f1); do
7797                         discard=$(($discard + $s))
7798         done
7799         cleanup_101a
7800
7801         if [[ $(($discard * 10)) -gt $nreads ]]; then
7802                 $LCTL get_param osc.*-osc*.rpc_stats
7803                 $LCTL get_param llite.*.read_ahead_stats
7804                 error "too many ($discard) discarded pages"
7805         fi
7806         rm -f $DIR/$tfile || true
7807 }
7808 run_test 101a "check read-ahead for random reads"
7809
7810 setup_test101bc() {
7811         test_mkdir $DIR/$tdir
7812         local ssize=$1
7813         local FILE_LENGTH=$2
7814         STRIPE_OFFSET=0
7815
7816         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
7817
7818         local list=$(comma_list $(osts_nodes))
7819         set_osd_param $list '' read_cache_enable 0
7820         set_osd_param $list '' writethrough_cache_enable 0
7821
7822         trap cleanup_test101bc EXIT
7823         # prepare the read-ahead file
7824         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
7825
7826         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
7827                                 count=$FILE_SIZE_MB 2> /dev/null
7828
7829 }
7830
7831 cleanup_test101bc() {
7832         trap 0
7833         rm -rf $DIR/$tdir
7834         rm -f $DIR/$tfile
7835
7836         local list=$(comma_list $(osts_nodes))
7837         set_osd_param $list '' read_cache_enable 1
7838         set_osd_param $list '' writethrough_cache_enable 1
7839 }
7840
7841 calc_total() {
7842         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
7843 }
7844
7845 ra_check_101() {
7846         local READ_SIZE=$1
7847         local STRIPE_SIZE=$2
7848         local FILE_LENGTH=$3
7849         local RA_INC=1048576
7850         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
7851         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
7852                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
7853         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
7854                         get_named_value 'read but discarded' |
7855                         cut -d" " -f1 | calc_total)
7856         if [[ $DISCARD -gt $discard_limit ]]; then
7857                 $LCTL get_param llite.*.read_ahead_stats
7858                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
7859         else
7860                 echo "Read-ahead success for size ${READ_SIZE}"
7861         fi
7862 }
7863
7864 test_101b() {
7865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7866         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7867
7868         local STRIPE_SIZE=1048576
7869         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
7870
7871         if [ $SLOW == "yes" ]; then
7872                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
7873         else
7874                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
7875         fi
7876
7877         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
7878
7879         # prepare the read-ahead file
7880         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
7881         cancel_lru_locks osc
7882         for BIDX in 2 4 8 16 32 64 128 256
7883         do
7884                 local BSIZE=$((BIDX*4096))
7885                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
7886                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
7887                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
7888                 $LCTL set_param -n llite.*.read_ahead_stats 0
7889                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
7890                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
7891                 cancel_lru_locks osc
7892                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
7893         done
7894         cleanup_test101bc
7895         true
7896 }
7897 run_test 101b "check stride-io mode read-ahead ================="
7898
7899 test_101c() {
7900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7901
7902         local STRIPE_SIZE=1048576
7903         local FILE_LENGTH=$((STRIPE_SIZE*100))
7904         local nreads=10000
7905         local rsize=65536
7906         local osc_rpc_stats
7907
7908         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
7909
7910         cancel_lru_locks osc
7911         $LCTL set_param osc.*.rpc_stats 0
7912         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
7913         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
7914                 local stats=$($LCTL get_param -n $osc_rpc_stats)
7915                 local lines=$(echo "$stats" | awk 'END {print NR;}')
7916                 local size
7917
7918                 if [ $lines -le 20 ]; then
7919                         continue
7920                 fi
7921                 for size in 1 2 4 8; do
7922                         local rpc=$(echo "$stats" |
7923                                     awk '($1 == "'$size':") {print $2; exit; }')
7924                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
7925                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
7926                 done
7927                 echo "$osc_rpc_stats check passed!"
7928         done
7929         cleanup_test101bc
7930         true
7931 }
7932 run_test 101c "check stripe_size aligned read-ahead ================="
7933
7934 set_read_ahead() {
7935         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
7936         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
7937 }
7938
7939 test_101d() {
7940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7941
7942         local file=$DIR/$tfile
7943         local sz_MB=${FILESIZE_101d:-500}
7944         local ra_MB=${READAHEAD_MB:-40}
7945
7946         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
7947         [ $free_MB -lt $sz_MB ] &&
7948                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
7949
7950         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
7951         $LFS setstripe -c -1 $file || error "setstripe failed"
7952
7953         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
7954         echo Cancel LRU locks on lustre client to flush the client cache
7955         cancel_lru_locks osc
7956
7957         echo Disable read-ahead
7958         local old_READAHEAD=$(set_read_ahead 0)
7959
7960         echo Reading the test file $file with read-ahead disabled
7961         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
7962
7963         echo Cancel LRU locks on lustre client to flush the client cache
7964         cancel_lru_locks osc
7965         echo Enable read-ahead with ${ra_MB}MB
7966         set_read_ahead $ra_MB
7967
7968         echo Reading the test file $file with read-ahead enabled
7969         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
7970
7971         echo "read-ahead disabled time read $raOFF"
7972         echo "read-ahead enabled  time read $raON"
7973
7974         set_read_ahead $old_READAHEAD
7975         rm -f $file
7976         wait_delete_completed
7977
7978         [ $raOFF -le 1 ] || [ $raON -lt $raOFF ] ||
7979                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
7980 }
7981 run_test 101d "file read with and without read-ahead enabled"
7982
7983 test_101e() {
7984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7985
7986         local file=$DIR/$tfile
7987         local size_KB=500  #KB
7988         local count=100
7989         local bsize=1024
7990
7991         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
7992         local need_KB=$((count * size_KB))
7993         [[ $free_KB -le $need_KB ]] &&
7994                 skip_env "Need free space $need_KB, have $free_KB"
7995
7996         echo "Creating $count ${size_KB}K test files"
7997         for ((i = 0; i < $count; i++)); do
7998                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
7999         done
8000
8001         echo "Cancel LRU locks on lustre client to flush the client cache"
8002         cancel_lru_locks $OSC
8003
8004         echo "Reset readahead stats"
8005         $LCTL set_param -n llite.*.read_ahead_stats 0
8006
8007         for ((i = 0; i < $count; i++)); do
8008                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
8009         done
8010
8011         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8012                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
8013
8014         for ((i = 0; i < $count; i++)); do
8015                 rm -rf $file.$i 2>/dev/null
8016         done
8017
8018         #10000 means 20% reads are missing in readahead
8019         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
8020 }
8021 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
8022
8023 test_101f() {
8024         which iozone || skip_env "no iozone installed"
8025
8026         local old_debug=$($LCTL get_param debug)
8027         old_debug=${old_debug#*=}
8028         $LCTL set_param debug="reada mmap"
8029
8030         # create a test file
8031         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
8032
8033         echo Cancel LRU locks on lustre client to flush the client cache
8034         cancel_lru_locks osc
8035
8036         echo Reset readahead stats
8037         $LCTL set_param -n llite.*.read_ahead_stats 0
8038
8039         echo mmap read the file with small block size
8040         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
8041                 > /dev/null 2>&1
8042
8043         echo checking missing pages
8044         $LCTL get_param llite.*.read_ahead_stats
8045         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8046                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8047
8048         $LCTL set_param debug="$old_debug"
8049         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
8050         rm -f $DIR/$tfile
8051 }
8052 run_test 101f "check mmap read performance"
8053
8054 test_101g_brw_size_test() {
8055         local mb=$1
8056         local pages=$((mb * 1048576 / PAGE_SIZE))
8057         local file=$DIR/$tfile
8058
8059         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
8060                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
8061         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
8062                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
8063                         return 2
8064         done
8065
8066         stack_trap "rm -f $file" EXIT
8067         $LCTL set_param -n osc.*.rpc_stats=0
8068
8069         # 10 RPCs should be enough for the test
8070         local count=10
8071         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
8072                 { error "dd write ${mb} MB blocks failed"; return 3; }
8073         cancel_lru_locks osc
8074         dd of=/dev/null if=$file bs=${mb}M count=$count ||
8075                 { error "dd write ${mb} MB blocks failed"; return 4; }
8076
8077         # calculate number of full-sized read and write RPCs
8078         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
8079                 sed -n '/pages per rpc/,/^$/p' |
8080                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
8081                 END { print reads,writes }'))
8082         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
8083                 return 5
8084         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
8085                 return 6
8086
8087         return 0
8088 }
8089
8090 test_101g() {
8091         remote_ost_nodsh && skip "remote OST with nodsh"
8092
8093         local rpcs
8094         local osts=$(get_facets OST)
8095         local list=$(comma_list $(osts_nodes))
8096         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8097         local brw_size="obdfilter.*.brw_size"
8098
8099         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8100
8101         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
8102
8103         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
8104                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
8105                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
8106            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
8107                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
8108                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
8109
8110                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
8111                         suffix="M"
8112
8113                 if [[ $orig_mb -lt 16 ]]; then
8114                         save_lustre_params $osts "$brw_size" > $p
8115                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
8116                                 error "set 16MB RPC size failed"
8117
8118                         echo "remount client to enable new RPC size"
8119                         remount_client $MOUNT || error "remount_client failed"
8120                 fi
8121
8122                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
8123                 # should be able to set brw_size=12, but no rpc_stats for that
8124                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
8125         fi
8126
8127         test_101g_brw_size_test 4 || error "4MB RPC test failed"
8128
8129         if [[ $orig_mb -lt 16 ]]; then
8130                 restore_lustre_params < $p
8131                 remount_client $MOUNT || error "remount_client restore failed"
8132         fi
8133
8134         rm -f $p $DIR/$tfile
8135 }
8136 run_test 101g "Big bulk(4/16 MiB) readahead"
8137
8138 setup_test102() {
8139         test_mkdir $DIR/$tdir
8140         chown $RUNAS_ID $DIR/$tdir
8141         STRIPE_SIZE=65536
8142         STRIPE_OFFSET=1
8143         STRIPE_COUNT=$OSTCOUNT
8144         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
8145
8146         trap cleanup_test102 EXIT
8147         cd $DIR
8148         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
8149         cd $DIR/$tdir
8150         for num in 1 2 3 4; do
8151                 for count in $(seq 1 $STRIPE_COUNT); do
8152                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
8153                                 local size=`expr $STRIPE_SIZE \* $num`
8154                                 local file=file"$num-$idx-$count"
8155                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
8156                         done
8157                 done
8158         done
8159
8160         cd $DIR
8161         $1 tar cf $TMP/f102.tar $tdir --xattrs
8162 }
8163
8164 cleanup_test102() {
8165         trap 0
8166         rm -f $TMP/f102.tar
8167         rm -rf $DIR/d0.sanity/d102
8168 }
8169
8170 test_102a() {
8171         [ "$UID" != 0 ] && skip "must run as root"
8172         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
8173                 skip_env "must have user_xattr"
8174
8175         [ -z "$(which setfattr 2>/dev/null)" ] &&
8176                 skip_env "could not find setfattr"
8177
8178         local testfile=$DIR/$tfile
8179
8180         touch $testfile
8181         echo "set/get xattr..."
8182         setfattr -n trusted.name1 -v value1 $testfile ||
8183                 error "setfattr -n trusted.name1=value1 $testfile failed"
8184         getfattr -n trusted.name1 $testfile 2> /dev/null |
8185           grep "trusted.name1=.value1" ||
8186                 error "$testfile missing trusted.name1=value1"
8187
8188         setfattr -n user.author1 -v author1 $testfile ||
8189                 error "setfattr -n user.author1=author1 $testfile failed"
8190         getfattr -n user.author1 $testfile 2> /dev/null |
8191           grep "user.author1=.author1" ||
8192                 error "$testfile missing trusted.author1=author1"
8193
8194         echo "listxattr..."
8195         setfattr -n trusted.name2 -v value2 $testfile ||
8196                 error "$testfile unable to set trusted.name2"
8197         setfattr -n trusted.name3 -v value3 $testfile ||
8198                 error "$testfile unable to set trusted.name3"
8199         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
8200             grep "trusted.name" | wc -l) -eq 3 ] ||
8201                 error "$testfile missing 3 trusted.name xattrs"
8202
8203         setfattr -n user.author2 -v author2 $testfile ||
8204                 error "$testfile unable to set user.author2"
8205         setfattr -n user.author3 -v author3 $testfile ||
8206                 error "$testfile unable to set user.author3"
8207         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
8208             grep "user.author" | wc -l) -eq 3 ] ||
8209                 error "$testfile missing 3 user.author xattrs"
8210
8211         echo "remove xattr..."
8212         setfattr -x trusted.name1 $testfile ||
8213                 error "$testfile error deleting trusted.name1"
8214         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
8215                 error "$testfile did not delete trusted.name1 xattr"
8216
8217         setfattr -x user.author1 $testfile ||
8218                 error "$testfile error deleting user.author1"
8219         echo "set lustre special xattr ..."
8220         $LFS setstripe -c1 $testfile
8221         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
8222                 awk -F "=" '/trusted.lov/ { print $2 }' )
8223         setfattr -n "trusted.lov" -v $lovea $testfile ||
8224                 error "$testfile doesn't ignore setting trusted.lov again"
8225         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
8226                 error "$testfile allow setting invalid trusted.lov"
8227         rm -f $testfile
8228 }
8229 run_test 102a "user xattr test =================================="
8230
8231 test_102b() {
8232         [ -z "$(which setfattr 2>/dev/null)" ] &&
8233                 skip_env "could not find setfattr"
8234         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8235
8236         # b10930: get/set/list trusted.lov xattr
8237         echo "get/set/list trusted.lov xattr ..."
8238         local testfile=$DIR/$tfile
8239         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8240                 error "setstripe failed"
8241         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
8242                 error "getstripe failed"
8243         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
8244                 error "can't get trusted.lov from $testfile"
8245
8246         local testfile2=${testfile}2
8247         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
8248                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
8249
8250         $MCREATE $testfile2
8251         setfattr -n trusted.lov -v $value $testfile2
8252         local stripe_size=$($LFS getstripe -S $testfile2)
8253         local stripe_count=$($LFS getstripe -c $testfile2)
8254         [[ $stripe_size -eq 65536 ]] ||
8255                 error "stripe size $stripe_size != 65536"
8256         [[ $stripe_count -eq $STRIPECOUNT ]] ||
8257                 error "stripe count $stripe_count != $STRIPECOUNT"
8258         rm -f $DIR/$tfile
8259 }
8260 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
8261
8262 test_102c() {
8263         [ -z "$(which setfattr 2>/dev/null)" ] &&
8264                 skip_env "could not find setfattr"
8265         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8266
8267         # b10930: get/set/list lustre.lov xattr
8268         echo "get/set/list lustre.lov xattr ..."
8269         test_mkdir $DIR/$tdir
8270         chown $RUNAS_ID $DIR/$tdir
8271         local testfile=$DIR/$tdir/$tfile
8272         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8273                 error "setstripe failed"
8274         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
8275                 error "getstripe failed"
8276         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
8277         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
8278
8279         local testfile2=${testfile}2
8280         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
8281                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
8282
8283         $RUNAS $MCREATE $testfile2
8284         $RUNAS setfattr -n lustre.lov -v $value $testfile2
8285         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
8286         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
8287         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
8288         [ $stripe_count -eq $STRIPECOUNT ] ||
8289                 error "stripe count $stripe_count != $STRIPECOUNT"
8290 }
8291 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
8292
8293 compare_stripe_info1() {
8294         local stripe_index_all_zero=true
8295
8296         for num in 1 2 3 4; do
8297                 for count in $(seq 1 $STRIPE_COUNT); do
8298                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
8299                                 local size=$((STRIPE_SIZE * num))
8300                                 local file=file"$num-$offset-$count"
8301                                 stripe_size=$($LFS getstripe -S $PWD/$file)
8302                                 [[ $stripe_size -ne $size ]] &&
8303                                     error "$file: size $stripe_size != $size"
8304                                 stripe_count=$($LFS getstripe -c $PWD/$file)
8305                                 # allow fewer stripes to be created, ORI-601
8306                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
8307                                     error "$file: count $stripe_count != $count"
8308                                 stripe_index=$($LFS getstripe -i $PWD/$file)
8309                                 [[ $stripe_index -ne 0 ]] &&
8310                                         stripe_index_all_zero=false
8311                         done
8312                 done
8313         done
8314         $stripe_index_all_zero &&
8315                 error "all files are being extracted starting from OST index 0"
8316         return 0
8317 }
8318
8319 have_xattrs_include() {
8320         tar --help | grep -q xattrs-include &&
8321                 echo --xattrs-include="lustre.*"
8322 }
8323
8324 test_102d() {
8325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8326         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8327
8328         XINC=$(have_xattrs_include)
8329         setup_test102
8330         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8331         cd $DIR/$tdir/$tdir
8332         compare_stripe_info1
8333 }
8334 run_test 102d "tar restore stripe info from tarfile,not keep osts"
8335
8336 test_102f() {
8337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8338         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8339
8340         XINC=$(have_xattrs_include)
8341         setup_test102
8342         test_mkdir $DIR/$tdir.restore
8343         cd $DIR
8344         tar cf - --xattrs $tdir | tar xf - \
8345                 -C $DIR/$tdir.restore --xattrs $XINC
8346         cd $DIR/$tdir.restore/$tdir
8347         compare_stripe_info1
8348 }
8349 run_test 102f "tar copy files, not keep osts"
8350
8351 grow_xattr() {
8352         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
8353                 skip "must have user_xattr"
8354         [ -z "$(which setfattr 2>/dev/null)" ] &&
8355                 skip_env "could not find setfattr"
8356         [ -z "$(which getfattr 2>/dev/null)" ] &&
8357                 skip_env "could not find getfattr"
8358
8359         local xsize=${1:-1024}  # in bytes
8360         local file=$DIR/$tfile
8361         local value="$(generate_string $xsize)"
8362         local xbig=trusted.big
8363         local toobig=$2
8364
8365         touch $file
8366         log "save $xbig on $file"
8367         if [ -z "$toobig" ]
8368         then
8369                 setfattr -n $xbig -v $value $file ||
8370                         error "saving $xbig on $file failed"
8371         else
8372                 setfattr -n $xbig -v $value $file &&
8373                         error "saving $xbig on $file succeeded"
8374                 return 0
8375         fi
8376
8377         local orig=$(get_xattr_value $xbig $file)
8378         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
8379
8380         local xsml=trusted.sml
8381         log "save $xsml on $file"
8382         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
8383
8384         local new=$(get_xattr_value $xbig $file)
8385         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
8386
8387         log "grow $xsml on $file"
8388         setfattr -n $xsml -v "$value" $file ||
8389                 error "growing $xsml on $file failed"
8390
8391         new=$(get_xattr_value $xbig $file)
8392         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
8393         log "$xbig still valid after growing $xsml"
8394
8395         rm -f $file
8396 }
8397
8398 test_102h() { # bug 15777
8399         grow_xattr 1024
8400 }
8401 run_test 102h "grow xattr from inside inode to external block"
8402
8403 test_102ha() {
8404         large_xattr_enabled || skip_env "ea_inode feature disabled"
8405
8406         echo "setting xattr of max xattr size: $(max_xattr_size)"
8407         grow_xattr $(max_xattr_size)
8408
8409         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
8410         echo "This should fail:"
8411         grow_xattr $(($(max_xattr_size) + 10)) 1
8412 }
8413 run_test 102ha "grow xattr from inside inode to external inode"
8414
8415 test_102i() { # bug 17038
8416         [ -z "$(which getfattr 2>/dev/null)" ] &&
8417                 skip "could not find getfattr"
8418
8419         touch $DIR/$tfile
8420         ln -s $DIR/$tfile $DIR/${tfile}link
8421         getfattr -n trusted.lov $DIR/$tfile ||
8422                 error "lgetxattr on $DIR/$tfile failed"
8423         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
8424                 grep -i "no such attr" ||
8425                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
8426         rm -f $DIR/$tfile $DIR/${tfile}link
8427 }
8428 run_test 102i "lgetxattr test on symbolic link ============"
8429
8430 test_102j() {
8431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8432         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8433
8434         XINC=$(have_xattrs_include)
8435         setup_test102 "$RUNAS"
8436         chown $RUNAS_ID $DIR/$tdir
8437         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8438         cd $DIR/$tdir/$tdir
8439         compare_stripe_info1 "$RUNAS"
8440 }
8441 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
8442
8443 test_102k() {
8444         [ -z "$(which setfattr 2>/dev/null)" ] &&
8445                 skip "could not find setfattr"
8446
8447         touch $DIR/$tfile
8448         # b22187 just check that does not crash for regular file.
8449         setfattr -n trusted.lov $DIR/$tfile
8450         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
8451         local test_kdir=$DIR/$tdir
8452         test_mkdir $test_kdir
8453         local default_size=$($LFS getstripe -S $test_kdir)
8454         local default_count=$($LFS getstripe -c $test_kdir)
8455         local default_offset=$($LFS getstripe -i $test_kdir)
8456         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
8457                 error 'dir setstripe failed'
8458         setfattr -n trusted.lov $test_kdir
8459         local stripe_size=$($LFS getstripe -S $test_kdir)
8460         local stripe_count=$($LFS getstripe -c $test_kdir)
8461         local stripe_offset=$($LFS getstripe -i $test_kdir)
8462         [ $stripe_size -eq $default_size ] ||
8463                 error "stripe size $stripe_size != $default_size"
8464         [ $stripe_count -eq $default_count ] ||
8465                 error "stripe count $stripe_count != $default_count"
8466         [ $stripe_offset -eq $default_offset ] ||
8467                 error "stripe offset $stripe_offset != $default_offset"
8468         rm -rf $DIR/$tfile $test_kdir
8469 }
8470 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
8471
8472 test_102l() {
8473         [ -z "$(which getfattr 2>/dev/null)" ] &&
8474                 skip "could not find getfattr"
8475
8476         # LU-532 trusted. xattr is invisible to non-root
8477         local testfile=$DIR/$tfile
8478
8479         touch $testfile
8480
8481         echo "listxattr as user..."
8482         chown $RUNAS_ID $testfile
8483         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
8484             grep -q "trusted" &&
8485                 error "$testfile trusted xattrs are user visible"
8486
8487         return 0;
8488 }
8489 run_test 102l "listxattr size test =================================="
8490
8491 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
8492         local path=$DIR/$tfile
8493         touch $path
8494
8495         listxattr_size_check $path || error "listattr_size_check $path failed"
8496 }
8497 run_test 102m "Ensure listxattr fails on small bufffer ========"
8498
8499 cleanup_test102
8500
8501 getxattr() { # getxattr path name
8502         # Return the base64 encoding of the value of xattr name on path.
8503         local path=$1
8504         local name=$2
8505
8506         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
8507         # file: $path
8508         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8509         #
8510         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8511
8512         getfattr --absolute-names --encoding=base64 --name=$name $path |
8513                 awk -F= -v name=$name '$1 == name {
8514                         print substr($0, index($0, "=") + 1);
8515         }'
8516 }
8517
8518 test_102n() { # LU-4101 mdt: protect internal xattrs
8519         [ -z "$(which setfattr 2>/dev/null)" ] &&
8520                 skip "could not find setfattr"
8521         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
8522         then
8523                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
8524         fi
8525
8526         local file0=$DIR/$tfile.0
8527         local file1=$DIR/$tfile.1
8528         local xattr0=$TMP/$tfile.0
8529         local xattr1=$TMP/$tfile.1
8530         local namelist="lov lma lmv link fid version som hsm"
8531         local name
8532         local value
8533
8534         rm -rf $file0 $file1 $xattr0 $xattr1
8535         touch $file0 $file1
8536
8537         # Get 'before' xattrs of $file1.
8538         getfattr --absolute-names --dump --match=- $file1 > $xattr0
8539
8540         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
8541                 namelist+=" lfsck_namespace"
8542         for name in $namelist; do
8543                 # Try to copy xattr from $file0 to $file1.
8544                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
8545
8546                 setfattr --name=trusted.$name --value="$value" $file1 ||
8547                         error "setxattr 'trusted.$name' failed"
8548
8549                 # Try to set a garbage xattr.
8550                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
8551
8552                 if [[ x$name == "xlov" ]]; then
8553                         setfattr --name=trusted.lov --value="$value" $file1 &&
8554                         error "setxattr invalid 'trusted.lov' success"
8555                 else
8556                         setfattr --name=trusted.$name --value="$value" $file1 ||
8557                                 error "setxattr invalid 'trusted.$name' failed"
8558                 fi
8559
8560                 # Try to remove the xattr from $file1. We don't care if this
8561                 # appears to succeed or fail, we just don't want there to be
8562                 # any changes or crashes.
8563                 setfattr --remove=$trusted.$name $file1 2> /dev/null
8564         done
8565
8566         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
8567         then
8568                 name="lfsck_ns"
8569                 # Try to copy xattr from $file0 to $file1.
8570                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
8571
8572                 setfattr --name=trusted.$name --value="$value" $file1 ||
8573                         error "setxattr 'trusted.$name' failed"
8574
8575                 # Try to set a garbage xattr.
8576                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
8577
8578                 setfattr --name=trusted.$name --value="$value" $file1 ||
8579                         error "setxattr 'trusted.$name' failed"
8580
8581                 # Try to remove the xattr from $file1. We don't care if this
8582                 # appears to succeed or fail, we just don't want there to be
8583                 # any changes or crashes.
8584                 setfattr --remove=$trusted.$name $file1 2> /dev/null
8585         fi
8586
8587         # Get 'after' xattrs of file1.
8588         getfattr --absolute-names --dump --match=- $file1 > $xattr1
8589
8590         if ! diff $xattr0 $xattr1; then
8591                 error "before and after xattrs of '$file1' differ"
8592         fi
8593
8594         rm -rf $file0 $file1 $xattr0 $xattr1
8595
8596         return 0
8597 }
8598 run_test 102n "silently ignore setxattr on internal trusted xattrs"
8599
8600 test_102p() { # LU-4703 setxattr did not check ownership
8601         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
8602                 skip "MDS needs to be at least 2.5.56"
8603
8604         local testfile=$DIR/$tfile
8605
8606         touch $testfile
8607
8608         echo "setfacl as user..."
8609         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
8610         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
8611
8612         echo "setfattr as user..."
8613         setfacl -m "u:$RUNAS_ID:---" $testfile
8614         $RUNAS setfattr -x system.posix_acl_access $testfile
8615         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
8616 }
8617 run_test 102p "check setxattr(2) correctly fails without permission"
8618
8619 test_102q() {
8620         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
8621                 skip "MDS needs to be at least 2.6.92"
8622
8623         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
8624 }
8625 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
8626
8627 test_102r() {
8628         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
8629                 skip "MDS needs to be at least 2.6.93"
8630
8631         touch $DIR/$tfile || error "touch"
8632         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
8633         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
8634         rm $DIR/$tfile || error "rm"
8635
8636         #normal directory
8637         mkdir -p $DIR/$tdir || error "mkdir"
8638         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
8639         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
8640         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
8641                 error "$testfile error deleting user.author1"
8642         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
8643                 grep "user.$(basename $tdir)" &&
8644                 error "$tdir did not delete user.$(basename $tdir)"
8645         rmdir $DIR/$tdir || error "rmdir"
8646
8647         #striped directory
8648         test_mkdir $DIR/$tdir
8649         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
8650         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
8651         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
8652                 error "$testfile error deleting user.author1"
8653         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
8654                 grep "user.$(basename $tdir)" &&
8655                 error "$tdir did not delete user.$(basename $tdir)"
8656         rmdir $DIR/$tdir || error "rm striped dir"
8657 }
8658 run_test 102r "set EAs with empty values"
8659
8660 test_102s() {
8661         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
8662                 skip "MDS needs to be at least 2.11.52"
8663
8664         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
8665
8666         save_lustre_params client "llite.*.xattr_cache" > $save
8667
8668         for cache in 0 1; do
8669                 lctl set_param llite.*.xattr_cache=$cache
8670
8671                 rm -f $DIR/$tfile
8672                 touch $DIR/$tfile || error "touch"
8673                 for prefix in lustre security system trusted user; do
8674                         # Note getxattr() may fail with 'Operation not
8675                         # supported' or 'No such attribute' depending
8676                         # on prefix and cache.
8677                         getfattr -n $prefix.n102s $DIR/$tfile &&
8678                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
8679                 done
8680         done
8681
8682         restore_lustre_params < $save
8683 }
8684 run_test 102s "getting nonexistent xattrs should fail"
8685
8686 test_102t() {
8687         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
8688                 skip "MDS needs to be at least 2.11.52"
8689
8690         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
8691
8692         save_lustre_params client "llite.*.xattr_cache" > $save
8693
8694         for cache in 0 1; do
8695                 lctl set_param llite.*.xattr_cache=$cache
8696
8697                 for buf_size in 0 256; do
8698                         rm -f $DIR/$tfile
8699                         touch $DIR/$tfile || error "touch"
8700                         setfattr -n user.multiop $DIR/$tfile
8701                         $MULTIOP $DIR/$tfile oa$buf_size ||
8702                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
8703                 done
8704         done
8705
8706         restore_lustre_params < $save
8707 }
8708 run_test 102t "zero length xattr values handled correctly"
8709
8710 run_acl_subtest()
8711 {
8712     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
8713     return $?
8714 }
8715
8716 test_103a() {
8717         [ "$UID" != 0 ] && skip "must run as root"
8718         $GSS && skip_env "could not run under gss"
8719         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
8720                 skip_env "must have acl enabled"
8721         [ -z "$(which setfacl 2>/dev/null)" ] &&
8722                 skip_env "could not find setfacl"
8723         remote_mds_nodsh && skip "remote MDS with nodsh"
8724
8725         gpasswd -a daemon bin                           # LU-5641
8726         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
8727
8728         declare -a identity_old
8729
8730         for num in $(seq $MDSCOUNT); do
8731                 switch_identity $num true || identity_old[$num]=$?
8732         done
8733
8734         SAVE_UMASK=$(umask)
8735         umask 0022
8736         mkdir -p $DIR/$tdir
8737         cd $DIR/$tdir
8738
8739         echo "performing cp ..."
8740         run_acl_subtest cp || error "run_acl_subtest cp failed"
8741         echo "performing getfacl-noacl..."
8742         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
8743         echo "performing misc..."
8744         run_acl_subtest misc || error  "misc test failed"
8745         echo "performing permissions..."
8746         run_acl_subtest permissions || error "permissions failed"
8747         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
8748         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
8749                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
8750                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
8751         then
8752                 echo "performing permissions xattr..."
8753                 run_acl_subtest permissions_xattr ||
8754                         error "permissions_xattr failed"
8755         fi
8756         echo "performing setfacl..."
8757         run_acl_subtest setfacl || error  "setfacl test failed"
8758
8759         # inheritance test got from HP
8760         echo "performing inheritance..."
8761         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
8762         chmod +x make-tree || error "chmod +x failed"
8763         run_acl_subtest inheritance || error "inheritance test failed"
8764         rm -f make-tree
8765
8766         echo "LU-974 ignore umask when acl is enabled..."
8767         run_acl_subtest 974 || error "LU-974 umask test failed"
8768         if [ $MDSCOUNT -ge 2 ]; then
8769                 run_acl_subtest 974_remote ||
8770                         error "LU-974 umask test failed under remote dir"
8771         fi
8772
8773         echo "LU-2561 newly created file is same size as directory..."
8774         if [ "$mds1_FSTYPE" != "zfs" ]; then
8775                 run_acl_subtest 2561 || error "LU-2561 test failed"
8776         else
8777                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
8778         fi
8779
8780         run_acl_subtest 4924 || error "LU-4924 test failed"
8781
8782         cd $SAVE_PWD
8783         umask $SAVE_UMASK
8784
8785         for num in $(seq $MDSCOUNT); do
8786                 if [ "${identity_old[$num]}" = 1 ]; then
8787                         switch_identity $num false || identity_old[$num]=$?
8788                 fi
8789         done
8790 }
8791 run_test 103a "acl test"
8792
8793 test_103b() {
8794         declare -a pids
8795         local U
8796
8797         for U in {0..511}; do
8798                 {
8799                 local O=$(printf "%04o" $U)
8800
8801                 umask $(printf "%04o" $((511 ^ $O)))
8802                 $LFS setstripe -c 1 $DIR/$tfile.s$O
8803                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
8804
8805                 (( $S == ($O & 0666) )) ||
8806                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
8807
8808                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
8809                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
8810                 (( $S == ($O & 0666) )) ||
8811                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
8812
8813                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
8814                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
8815                 (( $S == ($O & 0666) )) ||
8816                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
8817                 rm -f $DIR/$tfile.[smp]$0
8818                 } &
8819                 local pid=$!
8820
8821                 # limit the concurrently running threads to 64. LU-11878
8822                 local idx=$((U % 64))
8823                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
8824                 pids[idx]=$pid
8825         done
8826         wait
8827 }
8828 run_test 103b "umask lfs setstripe"
8829
8830 test_103c() {
8831         mkdir -p $DIR/$tdir
8832         cp -rp $DIR/$tdir $DIR/$tdir.bak
8833
8834         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
8835                 error "$DIR/$tdir shouldn't contain default ACL"
8836         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
8837                 error "$DIR/$tdir.bak shouldn't contain default ACL"
8838         true
8839 }
8840 run_test 103c "'cp -rp' won't set empty acl"
8841
8842 test_104a() {
8843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8844
8845         touch $DIR/$tfile
8846         lfs df || error "lfs df failed"
8847         lfs df -ih || error "lfs df -ih failed"
8848         lfs df -h $DIR || error "lfs df -h $DIR failed"
8849         lfs df -i $DIR || error "lfs df -i $DIR failed"
8850         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
8851         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
8852
8853         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
8854         lctl --device %$OSC deactivate
8855         lfs df || error "lfs df with deactivated OSC failed"
8856         lctl --device %$OSC activate
8857         # wait the osc back to normal
8858         wait_osc_import_ready client ost
8859
8860         lfs df || error "lfs df with reactivated OSC failed"
8861         rm -f $DIR/$tfile
8862 }
8863 run_test 104a "lfs df [-ih] [path] test ========================="
8864
8865 test_104b() {
8866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8867         [ $RUNAS_ID -eq $UID ] &&
8868                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8869
8870         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
8871                         grep "Permission denied" | wc -l)))
8872         if [ $denied_cnt -ne 0 ]; then
8873                 error "lfs check servers test failed"
8874         fi
8875 }
8876 run_test 104b "$RUNAS lfs check servers test ===================="
8877
8878 test_105a() {
8879         # doesn't work on 2.4 kernels
8880         touch $DIR/$tfile
8881         if $(flock_is_enabled); then
8882                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
8883         else
8884                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
8885         fi
8886         rm -f $DIR/$tfile
8887 }
8888 run_test 105a "flock when mounted without -o flock test ========"
8889
8890 test_105b() {
8891         touch $DIR/$tfile
8892         if $(flock_is_enabled); then
8893                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
8894         else
8895                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
8896         fi
8897         rm -f $DIR/$tfile
8898 }
8899 run_test 105b "fcntl when mounted without -o flock test ========"
8900
8901 test_105c() {
8902         touch $DIR/$tfile
8903         if $(flock_is_enabled); then
8904                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
8905         else
8906                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
8907         fi
8908         rm -f $DIR/$tfile
8909 }
8910 run_test 105c "lockf when mounted without -o flock test"
8911
8912 test_105d() { # bug 15924
8913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8914
8915         test_mkdir $DIR/$tdir
8916         flock_is_enabled || skip_env "mount w/o flock enabled"
8917         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
8918         $LCTL set_param fail_loc=0x80000315
8919         flocks_test 2 $DIR/$tdir
8920 }
8921 run_test 105d "flock race (should not freeze) ========"
8922
8923 test_105e() { # bug 22660 && 22040
8924         flock_is_enabled || skip_env "mount w/o flock enabled"
8925
8926         touch $DIR/$tfile
8927         flocks_test 3 $DIR/$tfile
8928 }
8929 run_test 105e "Two conflicting flocks from same process"
8930
8931 test_106() { #bug 10921
8932         test_mkdir $DIR/$tdir
8933         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
8934         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
8935 }
8936 run_test 106 "attempt exec of dir followed by chown of that dir"
8937
8938 test_107() {
8939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8940
8941         CDIR=`pwd`
8942         local file=core
8943
8944         cd $DIR
8945         rm -f $file
8946
8947         local save_pattern=$(sysctl -n kernel.core_pattern)
8948         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
8949         sysctl -w kernel.core_pattern=$file
8950         sysctl -w kernel.core_uses_pid=0
8951
8952         ulimit -c unlimited
8953         sleep 60 &
8954         SLEEPPID=$!
8955
8956         sleep 1
8957
8958         kill -s 11 $SLEEPPID
8959         wait $SLEEPPID
8960         if [ -e $file ]; then
8961                 size=`stat -c%s $file`
8962                 [ $size -eq 0 ] && error "Fail to create core file $file"
8963         else
8964                 error "Fail to create core file $file"
8965         fi
8966         rm -f $file
8967         sysctl -w kernel.core_pattern=$save_pattern
8968         sysctl -w kernel.core_uses_pid=$save_uses_pid
8969         cd $CDIR
8970 }
8971 run_test 107 "Coredump on SIG"
8972
8973 test_110() {
8974         test_mkdir $DIR/$tdir
8975         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
8976         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
8977                 error "mkdir with 256 char should fail, but did not"
8978         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
8979                 error "create with 255 char failed"
8980         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
8981                 error "create with 256 char should fail, but did not"
8982
8983         ls -l $DIR/$tdir
8984         rm -rf $DIR/$tdir
8985 }
8986 run_test 110 "filename length checking"
8987
8988 #
8989 # Purpose: To verify dynamic thread (OSS) creation.
8990 #
8991 test_115() {
8992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8993         remote_ost_nodsh && skip "remote OST with nodsh"
8994
8995         # Lustre does not stop service threads once they are started.
8996         # Reset number of running threads to default.
8997         stopall
8998         setupall
8999
9000         local OSTIO_pre
9001         local save_params="$TMP/sanity-$TESTNAME.parameters"
9002
9003         # Get ll_ost_io count before I/O
9004         OSTIO_pre=$(do_facet ost1 \
9005                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
9006         # Exit if lustre is not running (ll_ost_io not running).
9007         [ -z "$OSTIO_pre" ] && error "no OSS threads"
9008
9009         echo "Starting with $OSTIO_pre threads"
9010         local thread_max=$((OSTIO_pre * 2))
9011         local rpc_in_flight=$((thread_max * 2))
9012         # Number of I/O Process proposed to be started.
9013         local nfiles
9014         local facets=$(get_facets OST)
9015
9016         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
9017         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
9018
9019         # Set in_flight to $rpc_in_flight
9020         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
9021                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
9022         nfiles=${rpc_in_flight}
9023         # Set ost thread_max to $thread_max
9024         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
9025
9026         # 5 Minutes should be sufficient for max number of OSS
9027         # threads(thread_max) to be created.
9028         local timeout=300
9029
9030         # Start I/O.
9031         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
9032         test_mkdir $DIR/$tdir
9033         for i in $(seq $nfiles); do
9034                 local file=$DIR/$tdir/${tfile}-$i
9035                 $LFS setstripe -c -1 -i 0 $file
9036                 ($WTL $file $timeout)&
9037         done
9038
9039         # I/O Started - Wait for thread_started to reach thread_max or report
9040         # error if thread_started is more than thread_max.
9041         echo "Waiting for thread_started to reach thread_max"
9042         local thread_started=0
9043         local end_time=$((SECONDS + timeout))
9044
9045         while [ $SECONDS -le $end_time ] ; do
9046                 echo -n "."
9047                 # Get ost i/o thread_started count.
9048                 thread_started=$(do_facet ost1 \
9049                         "$LCTL get_param \
9050                         ost.OSS.ost_io.threads_started | cut -d= -f2")
9051                 # Break out if thread_started is equal/greater than thread_max
9052                 if [[ $thread_started -ge $thread_max ]]; then
9053                         echo ll_ost_io thread_started $thread_started, \
9054                                 equal/greater than thread_max $thread_max
9055                         break
9056                 fi
9057                 sleep 1
9058         done
9059
9060         # Cleanup - We have the numbers, Kill i/o jobs if running.
9061         jobcount=($(jobs -p))
9062         for i in $(seq 0 $((${#jobcount[@]}-1)))
9063         do
9064                 kill -9 ${jobcount[$i]}
9065                 if [ $? -ne 0 ] ; then
9066                         echo Warning: \
9067                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
9068                 fi
9069         done
9070
9071         # Cleanup files left by WTL binary.
9072         for i in $(seq $nfiles); do
9073                 local file=$DIR/$tdir/${tfile}-$i
9074                 rm -rf $file
9075                 if [ $? -ne 0 ] ; then
9076                         echo "Warning: Failed to delete file $file"
9077                 fi
9078         done
9079
9080         restore_lustre_params <$save_params
9081         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
9082
9083         # Error out if no new thread has started or Thread started is greater
9084         # than thread max.
9085         if [[ $thread_started -le $OSTIO_pre ||
9086                         $thread_started -gt $thread_max ]]; then
9087                 error "ll_ost_io: thread_started $thread_started" \
9088                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
9089                       "No new thread started or thread started greater " \
9090                       "than thread_max."
9091         fi
9092 }
9093 run_test 115 "verify dynamic thread creation===================="
9094
9095 free_min_max () {
9096         wait_delete_completed
9097         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
9098         echo "OST kbytes available: ${AVAIL[@]}"
9099         MAXV=${AVAIL[0]}
9100         MAXI=0
9101         MINV=${AVAIL[0]}
9102         MINI=0
9103         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
9104                 #echo OST $i: ${AVAIL[i]}kb
9105                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
9106                         MAXV=${AVAIL[i]}
9107                         MAXI=$i
9108                 fi
9109                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
9110                         MINV=${AVAIL[i]}
9111                         MINI=$i
9112                 fi
9113         done
9114         echo "Min free space: OST $MINI: $MINV"
9115         echo "Max free space: OST $MAXI: $MAXV"
9116 }
9117
9118 test_116a() { # was previously test_116()
9119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9120         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9121         remote_mds_nodsh && skip "remote MDS with nodsh"
9122
9123         echo -n "Free space priority "
9124         do_facet $SINGLEMDS lctl get_param -n lo*.*-mdtlov.qos_prio_free |
9125                 head -n1
9126         declare -a AVAIL
9127         free_min_max
9128
9129         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
9130         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
9131         trap simple_cleanup_common EXIT
9132
9133         # Check if we need to generate uneven OSTs
9134         test_mkdir -p $DIR/$tdir/OST${MINI}
9135         local FILL=$((MINV / 4))
9136         local DIFF=$((MAXV - MINV))
9137         local DIFF2=$((DIFF * 100 / MINV))
9138
9139         local threshold=$(do_facet $SINGLEMDS \
9140                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
9141         threshold=${threshold%%%}
9142         echo -n "Check for uneven OSTs: "
9143         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
9144
9145         if [[ $DIFF2 -gt $threshold ]]; then
9146                 echo "ok"
9147                 echo "Don't need to fill OST$MINI"
9148         else
9149                 # generate uneven OSTs. Write 2% over the QOS threshold value
9150                 echo "no"
9151                 DIFF=$((threshold - DIFF2 + 2))
9152                 DIFF2=$((MINV * DIFF / 100))
9153                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
9154                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
9155                         error "setstripe failed"
9156                 DIFF=$((DIFF2 / 2048))
9157                 i=0
9158                 while [ $i -lt $DIFF ]; do
9159                         i=$((i + 1))
9160                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
9161                                 bs=2M count=1 2>/dev/null
9162                         echo -n .
9163                 done
9164                 echo .
9165                 sync
9166                 sleep_maxage
9167                 free_min_max
9168         fi
9169
9170         DIFF=$((MAXV - MINV))
9171         DIFF2=$((DIFF * 100 / MINV))
9172         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
9173         if [ $DIFF2 -gt $threshold ]; then
9174                 echo "ok"
9175         else
9176                 echo "failed - QOS mode won't be used"
9177                 simple_cleanup_common
9178                 skip "QOS imbalance criteria not met"
9179         fi
9180
9181         MINI1=$MINI
9182         MINV1=$MINV
9183         MAXI1=$MAXI
9184         MAXV1=$MAXV
9185
9186         # now fill using QOS
9187         $LFS setstripe -c 1 $DIR/$tdir
9188         FILL=$((FILL / 200))
9189         if [ $FILL -gt 600 ]; then
9190                 FILL=600
9191         fi
9192         echo "writing $FILL files to QOS-assigned OSTs"
9193         i=0
9194         while [ $i -lt $FILL ]; do
9195                 i=$((i + 1))
9196                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
9197                         count=1 2>/dev/null
9198                 echo -n .
9199         done
9200         echo "wrote $i 200k files"
9201         sync
9202         sleep_maxage
9203
9204         echo "Note: free space may not be updated, so measurements might be off"
9205         free_min_max
9206         DIFF2=$((MAXV - MINV))
9207         echo "free space delta: orig $DIFF final $DIFF2"
9208         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
9209         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
9210         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
9211         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
9212         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
9213         if [[ $DIFF -gt 0 ]]; then
9214                 FILL=$((DIFF2 * 100 / DIFF - 100))
9215                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
9216         fi
9217
9218         # Figure out which files were written where
9219         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9220                awk '/'$MINI1': / {print $2; exit}')
9221         echo $UUID
9222         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9223         echo "$MINC files created on smaller OST $MINI1"
9224         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9225                awk '/'$MAXI1': / {print $2; exit}')
9226         echo $UUID
9227         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9228         echo "$MAXC files created on larger OST $MAXI1"
9229         if [[ $MINC -gt 0 ]]; then
9230                 FILL=$((MAXC * 100 / MINC - 100))
9231                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
9232         fi
9233         [[ $MAXC -gt $MINC ]] ||
9234                 error_ignore LU-9 "stripe QOS didn't balance free space"
9235         simple_cleanup_common
9236 }
9237 run_test 116a "stripe QOS: free space balance ==================="
9238
9239 test_116b() { # LU-2093
9240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9241         remote_mds_nodsh && skip "remote MDS with nodsh"
9242
9243 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
9244         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
9245                        lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
9246         [ -z "$old_rr" ] && skip "no QOS"
9247         do_facet $SINGLEMDS lctl set_param \
9248                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
9249         mkdir -p $DIR/$tdir
9250         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
9251         createmany -o $DIR/$tdir/f- 20 || error "can't create"
9252         do_facet $SINGLEMDS lctl set_param fail_loc=0
9253         rm -rf $DIR/$tdir
9254         do_facet $SINGLEMDS lctl set_param \
9255                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
9256 }
9257 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
9258
9259 test_117() # bug 10891
9260 {
9261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9262
9263         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
9264         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
9265         lctl set_param fail_loc=0x21e
9266         > $DIR/$tfile || error "truncate failed"
9267         lctl set_param fail_loc=0
9268         echo "Truncate succeeded."
9269         rm -f $DIR/$tfile
9270 }
9271 run_test 117 "verify osd extend =========="
9272
9273 NO_SLOW_RESENDCOUNT=4
9274 export OLD_RESENDCOUNT=""
9275 set_resend_count () {
9276         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
9277         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
9278         lctl set_param -n $PROC_RESENDCOUNT $1
9279         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
9280 }
9281
9282 # for reduce test_118* time (b=14842)
9283 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9284
9285 # Reset async IO behavior after error case
9286 reset_async() {
9287         FILE=$DIR/reset_async
9288
9289         # Ensure all OSCs are cleared
9290         $LFS setstripe -c -1 $FILE
9291         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
9292         sync
9293         rm $FILE
9294 }
9295
9296 test_118a() #bug 11710
9297 {
9298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9299
9300         reset_async
9301
9302         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9303         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9304         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9305
9306         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9307                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9308                 return 1;
9309         fi
9310         rm -f $DIR/$tfile
9311 }
9312 run_test 118a "verify O_SYNC works =========="
9313
9314 test_118b()
9315 {
9316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9317         remote_ost_nodsh && skip "remote OST with nodsh"
9318
9319         reset_async
9320
9321         #define OBD_FAIL_SRV_ENOENT 0x217
9322         set_nodes_failloc "$(osts_nodes)" 0x217
9323         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9324         RC=$?
9325         set_nodes_failloc "$(osts_nodes)" 0
9326         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9327         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9328                     grep -c writeback)
9329
9330         if [[ $RC -eq 0 ]]; then
9331                 error "Must return error due to dropped pages, rc=$RC"
9332                 return 1;
9333         fi
9334
9335         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9336                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9337                 return 1;
9338         fi
9339
9340         echo "Dirty pages not leaked on ENOENT"
9341
9342         # Due to the above error the OSC will issue all RPCs syncronously
9343         # until a subsequent RPC completes successfully without error.
9344         $MULTIOP $DIR/$tfile Ow4096yc
9345         rm -f $DIR/$tfile
9346
9347         return 0
9348 }
9349 run_test 118b "Reclaim dirty pages on fatal error =========="
9350
9351 test_118c()
9352 {
9353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9354
9355         # for 118c, restore the original resend count, LU-1940
9356         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
9357                                 set_resend_count $OLD_RESENDCOUNT
9358         remote_ost_nodsh && skip "remote OST with nodsh"
9359
9360         reset_async
9361
9362         #define OBD_FAIL_OST_EROFS               0x216
9363         set_nodes_failloc "$(osts_nodes)" 0x216
9364
9365         # multiop should block due to fsync until pages are written
9366         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9367         MULTIPID=$!
9368         sleep 1
9369
9370         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9371                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9372         fi
9373
9374         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9375                     grep -c writeback)
9376         if [[ $WRITEBACK -eq 0 ]]; then
9377                 error "No page in writeback, writeback=$WRITEBACK"
9378         fi
9379
9380         set_nodes_failloc "$(osts_nodes)" 0
9381         wait $MULTIPID
9382         RC=$?
9383         if [[ $RC -ne 0 ]]; then
9384                 error "Multiop fsync failed, rc=$RC"
9385         fi
9386
9387         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9388         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9389                     grep -c writeback)
9390         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9391                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9392         fi
9393
9394         rm -f $DIR/$tfile
9395         echo "Dirty pages flushed via fsync on EROFS"
9396         return 0
9397 }
9398 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
9399
9400 # continue to use small resend count to reduce test_118* time (b=14842)
9401 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9402
9403 test_118d()
9404 {
9405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9406         remote_ost_nodsh && skip "remote OST with nodsh"
9407
9408         reset_async
9409
9410         #define OBD_FAIL_OST_BRW_PAUSE_BULK
9411         set_nodes_failloc "$(osts_nodes)" 0x214
9412         # multiop should block due to fsync until pages are written
9413         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9414         MULTIPID=$!
9415         sleep 1
9416
9417         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9418                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9419         fi
9420
9421         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9422                     grep -c writeback)
9423         if [[ $WRITEBACK -eq 0 ]]; then
9424                 error "No page in writeback, writeback=$WRITEBACK"
9425         fi
9426
9427         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
9428         set_nodes_failloc "$(osts_nodes)" 0
9429
9430         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9431         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9432                     grep -c writeback)
9433         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9434                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9435         fi
9436
9437         rm -f $DIR/$tfile
9438         echo "Dirty pages gaurenteed flushed via fsync"
9439         return 0
9440 }
9441 run_test 118d "Fsync validation inject a delay of the bulk =========="
9442
9443 test_118f() {
9444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9445
9446         reset_async
9447
9448         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
9449         lctl set_param fail_loc=0x8000040a
9450
9451         # Should simulate EINVAL error which is fatal
9452         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9453         RC=$?
9454         if [[ $RC -eq 0 ]]; then
9455                 error "Must return error due to dropped pages, rc=$RC"
9456         fi
9457
9458         lctl set_param fail_loc=0x0
9459
9460         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9461         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9462         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9463                     grep -c writeback)
9464         if [[ $LOCKED -ne 0 ]]; then
9465                 error "Locked pages remain in cache, locked=$LOCKED"
9466         fi
9467
9468         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9469                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9470         fi
9471
9472         rm -f $DIR/$tfile
9473         echo "No pages locked after fsync"
9474
9475         reset_async
9476         return 0
9477 }
9478 run_test 118f "Simulate unrecoverable OSC side error =========="
9479
9480 test_118g() {
9481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9482
9483         reset_async
9484
9485         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9486         lctl set_param fail_loc=0x406
9487
9488         # simulate local -ENOMEM
9489         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9490         RC=$?
9491
9492         lctl set_param fail_loc=0
9493         if [[ $RC -eq 0 ]]; then
9494                 error "Must return error due to dropped pages, rc=$RC"
9495         fi
9496
9497         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9498         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9499         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9500                         grep -c writeback)
9501         if [[ $LOCKED -ne 0 ]]; then
9502                 error "Locked pages remain in cache, locked=$LOCKED"
9503         fi
9504
9505         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9506                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9507         fi
9508
9509         rm -f $DIR/$tfile
9510         echo "No pages locked after fsync"
9511
9512         reset_async
9513         return 0
9514 }
9515 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
9516
9517 test_118h() {
9518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9519         remote_ost_nodsh && skip "remote OST with nodsh"
9520
9521         reset_async
9522
9523         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9524         set_nodes_failloc "$(osts_nodes)" 0x20e
9525         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
9526         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9527         RC=$?
9528
9529         set_nodes_failloc "$(osts_nodes)" 0
9530         if [[ $RC -eq 0 ]]; then
9531                 error "Must return error due to dropped pages, rc=$RC"
9532         fi
9533
9534         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9535         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9536         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9537                     grep -c writeback)
9538         if [[ $LOCKED -ne 0 ]]; then
9539                 error "Locked pages remain in cache, locked=$LOCKED"
9540         fi
9541
9542         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9543                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9544         fi
9545
9546         rm -f $DIR/$tfile
9547         echo "No pages locked after fsync"
9548
9549         return 0
9550 }
9551 run_test 118h "Verify timeout in handling recoverables errors  =========="
9552
9553 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
9554
9555 test_118i() {
9556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9557         remote_ost_nodsh && skip "remote OST with nodsh"
9558
9559         reset_async
9560
9561         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9562         set_nodes_failloc "$(osts_nodes)" 0x20e
9563
9564         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
9565         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9566         PID=$!
9567         sleep 5
9568         set_nodes_failloc "$(osts_nodes)" 0
9569
9570         wait $PID
9571         RC=$?
9572         if [[ $RC -ne 0 ]]; then
9573                 error "got error, but should be not, rc=$RC"
9574         fi
9575
9576         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9577         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9578         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9579         if [[ $LOCKED -ne 0 ]]; then
9580                 error "Locked pages remain in cache, locked=$LOCKED"
9581         fi
9582
9583         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9584                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9585         fi
9586
9587         rm -f $DIR/$tfile
9588         echo "No pages locked after fsync"
9589
9590         return 0
9591 }
9592 run_test 118i "Fix error before timeout in recoverable error  =========="
9593
9594 [ "$SLOW" = "no" ] && set_resend_count 4
9595
9596 test_118j() {
9597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9598         remote_ost_nodsh && skip "remote OST with nodsh"
9599
9600         reset_async
9601
9602         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
9603         set_nodes_failloc "$(osts_nodes)" 0x220
9604
9605         # return -EIO from OST
9606         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9607         RC=$?
9608         set_nodes_failloc "$(osts_nodes)" 0x0
9609         if [[ $RC -eq 0 ]]; then
9610                 error "Must return error due to dropped pages, rc=$RC"
9611         fi
9612
9613         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9614         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9615         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9616         if [[ $LOCKED -ne 0 ]]; then
9617                 error "Locked pages remain in cache, locked=$LOCKED"
9618         fi
9619
9620         # in recoverable error on OST we want resend and stay until it finished
9621         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9622                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9623         fi
9624
9625         rm -f $DIR/$tfile
9626         echo "No pages locked after fsync"
9627
9628         return 0
9629 }
9630 run_test 118j "Simulate unrecoverable OST side error =========="
9631
9632 test_118k()
9633 {
9634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9635         remote_ost_nodsh && skip "remote OSTs with nodsh"
9636
9637         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9638         set_nodes_failloc "$(osts_nodes)" 0x20e
9639         test_mkdir $DIR/$tdir
9640
9641         for ((i=0;i<10;i++)); do
9642                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
9643                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
9644                 SLEEPPID=$!
9645                 sleep 0.500s
9646                 kill $SLEEPPID
9647                 wait $SLEEPPID
9648         done
9649
9650         set_nodes_failloc "$(osts_nodes)" 0
9651         rm -rf $DIR/$tdir
9652 }
9653 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
9654
9655 test_118l() # LU-646
9656 {
9657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9658
9659         test_mkdir $DIR/$tdir
9660         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
9661         rm -rf $DIR/$tdir
9662 }
9663 run_test 118l "fsync dir"
9664
9665 test_118m() # LU-3066
9666 {
9667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9668
9669         test_mkdir $DIR/$tdir
9670         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
9671         rm -rf $DIR/$tdir
9672 }
9673 run_test 118m "fdatasync dir ========="
9674
9675 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
9676
9677 test_118n()
9678 {
9679         local begin
9680         local end
9681
9682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9683         remote_ost_nodsh && skip "remote OSTs with nodsh"
9684
9685         # Sleep to avoid a cached response.
9686         #define OBD_STATFS_CACHE_SECONDS 1
9687         sleep 2
9688
9689         # Inject a 10 second delay in the OST_STATFS handler.
9690         #define OBD_FAIL_OST_STATFS_DELAY 0x242
9691         set_nodes_failloc "$(osts_nodes)" 0x242
9692
9693         begin=$SECONDS
9694         stat --file-system $MOUNT > /dev/null
9695         end=$SECONDS
9696
9697         set_nodes_failloc "$(osts_nodes)" 0
9698
9699         if ((end - begin > 20)); then
9700             error "statfs took $((end - begin)) seconds, expected 10"
9701         fi
9702 }
9703 run_test 118n "statfs() sends OST_STATFS requests in parallel"
9704
9705 test_119a() # bug 11737
9706 {
9707         BSIZE=$((512 * 1024))
9708         directio write $DIR/$tfile 0 1 $BSIZE
9709         # We ask to read two blocks, which is more than a file size.
9710         # directio will indicate an error when requested and actual
9711         # sizes aren't equeal (a normal situation in this case) and
9712         # print actual read amount.
9713         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
9714         if [ "$NOB" != "$BSIZE" ]; then
9715                 error "read $NOB bytes instead of $BSIZE"
9716         fi
9717         rm -f $DIR/$tfile
9718 }
9719 run_test 119a "Short directIO read must return actual read amount"
9720
9721 test_119b() # bug 11737
9722 {
9723         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9724
9725         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
9726         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
9727         sync
9728         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
9729                 error "direct read failed"
9730         rm -f $DIR/$tfile
9731 }
9732 run_test 119b "Sparse directIO read must return actual read amount"
9733
9734 test_119c() # bug 13099
9735 {
9736         BSIZE=1048576
9737         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
9738         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
9739         rm -f $DIR/$tfile
9740 }
9741 run_test 119c "Testing for direct read hitting hole"
9742
9743 test_119d() # bug 15950
9744 {
9745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9746
9747         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
9748         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
9749         BSIZE=1048576
9750         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
9751         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
9752         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
9753         lctl set_param fail_loc=0x40d
9754         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
9755         pid_dio=$!
9756         sleep 1
9757         cat $DIR/$tfile > /dev/null &
9758         lctl set_param fail_loc=0
9759         pid_reads=$!
9760         wait $pid_dio
9761         log "the DIO writes have completed, now wait for the reads (should not block very long)"
9762         sleep 2
9763         [ -n "`ps h -p $pid_reads -o comm`" ] && \
9764         error "the read rpcs have not completed in 2s"
9765         rm -f $DIR/$tfile
9766         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
9767 }
9768 run_test 119d "The DIO path should try to send a new rpc once one is completed"
9769
9770 test_120a() {
9771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9772         remote_mds_nodsh && skip "remote MDS with nodsh"
9773         test_mkdir -i0 -c1 $DIR/$tdir
9774         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9775                 skip_env "no early lock cancel on server"
9776
9777         lru_resize_disable mdc
9778         lru_resize_disable osc
9779         cancel_lru_locks mdc
9780         # asynchronous object destroy at MDT could cause bl ast to client
9781         cancel_lru_locks osc
9782
9783         stat $DIR/$tdir > /dev/null
9784         can1=$(do_facet mds1 \
9785                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9786                awk '/ldlm_cancel/ {print $2}')
9787         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9788                awk '/ldlm_bl_callback/ {print $2}')
9789         test_mkdir -i0 -c1 $DIR/$tdir/d1
9790         can2=$(do_facet mds1 \
9791                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9792                awk '/ldlm_cancel/ {print $2}')
9793         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9794                awk '/ldlm_bl_callback/ {print $2}')
9795         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9796         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9797         lru_resize_enable mdc
9798         lru_resize_enable osc
9799 }
9800 run_test 120a "Early Lock Cancel: mkdir test"
9801
9802 test_120b() {
9803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9804         remote_mds_nodsh && skip "remote MDS with nodsh"
9805         test_mkdir $DIR/$tdir
9806         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9807                 skip_env "no early lock cancel on server"
9808
9809         lru_resize_disable mdc
9810         lru_resize_disable osc
9811         cancel_lru_locks mdc
9812         stat $DIR/$tdir > /dev/null
9813         can1=$(do_facet $SINGLEMDS \
9814                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9815                awk '/ldlm_cancel/ {print $2}')
9816         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9817                awk '/ldlm_bl_callback/ {print $2}')
9818         touch $DIR/$tdir/f1
9819         can2=$(do_facet $SINGLEMDS \
9820                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9821                awk '/ldlm_cancel/ {print $2}')
9822         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9823                awk '/ldlm_bl_callback/ {print $2}')
9824         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9825         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9826         lru_resize_enable mdc
9827         lru_resize_enable osc
9828 }
9829 run_test 120b "Early Lock Cancel: create test"
9830
9831 test_120c() {
9832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9833         remote_mds_nodsh && skip "remote MDS with nodsh"
9834         test_mkdir -i0 -c1 $DIR/$tdir
9835         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9836                 skip "no early lock cancel on server"
9837
9838         lru_resize_disable mdc
9839         lru_resize_disable osc
9840         test_mkdir -i0 -c1 $DIR/$tdir/d1
9841         test_mkdir -i0 -c1 $DIR/$tdir/d2
9842         touch $DIR/$tdir/d1/f1
9843         cancel_lru_locks mdc
9844         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
9845         can1=$(do_facet mds1 \
9846                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9847                awk '/ldlm_cancel/ {print $2}')
9848         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9849                awk '/ldlm_bl_callback/ {print $2}')
9850         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
9851         can2=$(do_facet mds1 \
9852                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9853                awk '/ldlm_cancel/ {print $2}')
9854         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9855                awk '/ldlm_bl_callback/ {print $2}')
9856         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9857         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9858         lru_resize_enable mdc
9859         lru_resize_enable osc
9860 }
9861 run_test 120c "Early Lock Cancel: link test"
9862
9863 test_120d() {
9864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9865         remote_mds_nodsh && skip "remote MDS with nodsh"
9866         test_mkdir -i0 -c1 $DIR/$tdir
9867         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9868                 skip_env "no early lock cancel on server"
9869
9870         lru_resize_disable mdc
9871         lru_resize_disable osc
9872         touch $DIR/$tdir
9873         cancel_lru_locks mdc
9874         stat $DIR/$tdir > /dev/null
9875         can1=$(do_facet mds1 \
9876                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9877                awk '/ldlm_cancel/ {print $2}')
9878         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9879                awk '/ldlm_bl_callback/ {print $2}')
9880         chmod a+x $DIR/$tdir
9881         can2=$(do_facet mds1 \
9882                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9883                awk '/ldlm_cancel/ {print $2}')
9884         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9885                awk '/ldlm_bl_callback/ {print $2}')
9886         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9887         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9888         lru_resize_enable mdc
9889         lru_resize_enable osc
9890 }
9891 run_test 120d "Early Lock Cancel: setattr test"
9892
9893 test_120e() {
9894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9895         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9896                 skip_env "no early lock cancel on server"
9897         remote_mds_nodsh && skip "remote MDS with nodsh"
9898
9899         local dlmtrace_set=false
9900
9901         test_mkdir -i0 -c1 $DIR/$tdir
9902         lru_resize_disable mdc
9903         lru_resize_disable osc
9904         ! $LCTL get_param debug | grep -q dlmtrace &&
9905                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
9906         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
9907         cancel_lru_locks mdc
9908         cancel_lru_locks osc
9909         dd if=$DIR/$tdir/f1 of=/dev/null
9910         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
9911         # XXX client can not do early lock cancel of OST lock
9912         # during unlink (LU-4206), so cancel osc lock now.
9913         sleep 2
9914         cancel_lru_locks osc
9915         can1=$(do_facet mds1 \
9916                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9917                awk '/ldlm_cancel/ {print $2}')
9918         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9919                awk '/ldlm_bl_callback/ {print $2}')
9920         unlink $DIR/$tdir/f1
9921         sleep 5
9922         can2=$(do_facet mds1 \
9923                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9924                awk '/ldlm_cancel/ {print $2}')
9925         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9926                awk '/ldlm_bl_callback/ {print $2}')
9927         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
9928                 $LCTL dk $TMP/cancel.debug.txt
9929         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
9930                 $LCTL dk $TMP/blocking.debug.txt
9931         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
9932         lru_resize_enable mdc
9933         lru_resize_enable osc
9934 }
9935 run_test 120e "Early Lock Cancel: unlink test"
9936
9937 test_120f() {
9938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9939         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9940                 skip_env "no early lock cancel on server"
9941         remote_mds_nodsh && skip "remote MDS with nodsh"
9942
9943         test_mkdir -i0 -c1 $DIR/$tdir
9944         lru_resize_disable mdc
9945         lru_resize_disable osc
9946         test_mkdir -i0 -c1 $DIR/$tdir/d1
9947         test_mkdir -i0 -c1 $DIR/$tdir/d2
9948         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
9949         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
9950         cancel_lru_locks mdc
9951         cancel_lru_locks osc
9952         dd if=$DIR/$tdir/d1/f1 of=/dev/null
9953         dd if=$DIR/$tdir/d2/f2 of=/dev/null
9954         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
9955         # XXX client can not do early lock cancel of OST lock
9956         # during rename (LU-4206), so cancel osc lock now.
9957         sleep 2
9958         cancel_lru_locks osc
9959         can1=$(do_facet mds1 \
9960                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9961                awk '/ldlm_cancel/ {print $2}')
9962         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9963                awk '/ldlm_bl_callback/ {print $2}')
9964         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
9965         sleep 5
9966         can2=$(do_facet mds1 \
9967                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9968                awk '/ldlm_cancel/ {print $2}')
9969         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9970                awk '/ldlm_bl_callback/ {print $2}')
9971         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9972         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9973         lru_resize_enable mdc
9974         lru_resize_enable osc
9975 }
9976 run_test 120f "Early Lock Cancel: rename test"
9977
9978 test_120g() {
9979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9980         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9981                 skip_env "no early lock cancel on server"
9982         remote_mds_nodsh && skip "remote MDS with nodsh"
9983
9984         lru_resize_disable mdc
9985         lru_resize_disable osc
9986         count=10000
9987         echo create $count files
9988         test_mkdir $DIR/$tdir
9989         cancel_lru_locks mdc
9990         cancel_lru_locks osc
9991         t0=$(date +%s)
9992
9993         can0=$(do_facet $SINGLEMDS \
9994                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9995                awk '/ldlm_cancel/ {print $2}')
9996         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9997                awk '/ldlm_bl_callback/ {print $2}')
9998         createmany -o $DIR/$tdir/f $count
9999         sync
10000         can1=$(do_facet $SINGLEMDS \
10001                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10002                awk '/ldlm_cancel/ {print $2}')
10003         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10004                awk '/ldlm_bl_callback/ {print $2}')
10005         t1=$(date +%s)
10006         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
10007         echo rm $count files
10008         rm -r $DIR/$tdir
10009         sync
10010         can2=$(do_facet $SINGLEMDS \
10011                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10012                awk '/ldlm_cancel/ {print $2}')
10013         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10014                awk '/ldlm_bl_callback/ {print $2}')
10015         t2=$(date +%s)
10016         echo total: $count removes in $((t2-t1))
10017         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
10018         sleep 2
10019         # wait for commitment of removal
10020         lru_resize_enable mdc
10021         lru_resize_enable osc
10022 }
10023 run_test 120g "Early Lock Cancel: performance test"
10024
10025 test_121() { #bug #10589
10026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10027
10028         rm -rf $DIR/$tfile
10029         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
10030 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
10031         lctl set_param fail_loc=0x310
10032         cancel_lru_locks osc > /dev/null
10033         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
10034         lctl set_param fail_loc=0
10035         [[ $reads -eq $writes ]] ||
10036                 error "read $reads blocks, must be $writes blocks"
10037 }
10038 run_test 121 "read cancel race ========="
10039
10040 test_123a() { # was test 123, statahead(bug 11401)
10041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10042
10043         SLOWOK=0
10044         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
10045                 log "testing UP system. Performance may be lower than expected."
10046                 SLOWOK=1
10047         fi
10048
10049         rm -rf $DIR/$tdir
10050         test_mkdir $DIR/$tdir
10051         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
10052         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
10053         MULT=10
10054         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
10055                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
10056
10057                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10058                 lctl set_param -n llite.*.statahead_max 0
10059                 lctl get_param llite.*.statahead_max
10060                 cancel_lru_locks mdc
10061                 cancel_lru_locks osc
10062                 stime=`date +%s`
10063                 time ls -l $DIR/$tdir | wc -l
10064                 etime=`date +%s`
10065                 delta=$((etime - stime))
10066                 log "ls $i files without statahead: $delta sec"
10067                 lctl set_param llite.*.statahead_max=$max
10068
10069                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10070                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
10071                 cancel_lru_locks mdc
10072                 cancel_lru_locks osc
10073                 stime=`date +%s`
10074                 time ls -l $DIR/$tdir | wc -l
10075                 etime=`date +%s`
10076                 delta_sa=$((etime - stime))
10077                 log "ls $i files with statahead: $delta_sa sec"
10078                 lctl get_param -n llite.*.statahead_stats
10079                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10080
10081                 [[ $swrong -lt $ewrong ]] &&
10082                         log "statahead was stopped, maybe too many locks held!"
10083                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
10084
10085                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10086                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10087                     lctl set_param -n llite.*.statahead_max 0
10088                     lctl get_param llite.*.statahead_max
10089                     cancel_lru_locks mdc
10090                     cancel_lru_locks osc
10091                     stime=`date +%s`
10092                     time ls -l $DIR/$tdir | wc -l
10093                     etime=`date +%s`
10094                     delta=$((etime - stime))
10095                     log "ls $i files again without statahead: $delta sec"
10096                     lctl set_param llite.*.statahead_max=$max
10097                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10098                         if [  $SLOWOK -eq 0 ]; then
10099                                 error "ls $i files is slower with statahead!"
10100                         else
10101                                 log "ls $i files is slower with statahead!"
10102                         fi
10103                         break
10104                     fi
10105                 fi
10106
10107                 [ $delta -gt 20 ] && break
10108                 [ $delta -gt 8 ] && MULT=$((50 / delta))
10109                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
10110         done
10111         log "ls done"
10112
10113         stime=`date +%s`
10114         rm -r $DIR/$tdir
10115         sync
10116         etime=`date +%s`
10117         delta=$((etime - stime))
10118         log "rm -r $DIR/$tdir/: $delta seconds"
10119         log "rm done"
10120         lctl get_param -n llite.*.statahead_stats
10121 }
10122 run_test 123a "verify statahead work"
10123
10124 test_123b () { # statahead(bug 15027)
10125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10126
10127         test_mkdir $DIR/$tdir
10128         createmany -o $DIR/$tdir/$tfile-%d 1000
10129
10130         cancel_lru_locks mdc
10131         cancel_lru_locks osc
10132
10133 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
10134         lctl set_param fail_loc=0x80000803
10135         ls -lR $DIR/$tdir > /dev/null
10136         log "ls done"
10137         lctl set_param fail_loc=0x0
10138         lctl get_param -n llite.*.statahead_stats
10139         rm -r $DIR/$tdir
10140         sync
10141
10142 }
10143 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
10144
10145 test_124a() {
10146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10147         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10148                 skip_env "no lru resize on server"
10149
10150         local NR=2000
10151
10152         test_mkdir $DIR/$tdir
10153
10154         log "create $NR files at $DIR/$tdir"
10155         createmany -o $DIR/$tdir/f $NR ||
10156                 error "failed to create $NR files in $DIR/$tdir"
10157
10158         cancel_lru_locks mdc
10159         ls -l $DIR/$tdir > /dev/null
10160
10161         local NSDIR=""
10162         local LRU_SIZE=0
10163         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
10164                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
10165                 LRU_SIZE=$($LCTL get_param -n $PARAM)
10166                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
10167                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
10168                         log "NSDIR=$NSDIR"
10169                         log "NS=$(basename $NSDIR)"
10170                         break
10171                 fi
10172         done
10173
10174         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
10175                 skip "Not enough cached locks created!"
10176         fi
10177         log "LRU=$LRU_SIZE"
10178
10179         local SLEEP=30
10180
10181         # We know that lru resize allows one client to hold $LIMIT locks
10182         # for 10h. After that locks begin to be killed by client.
10183         local MAX_HRS=10
10184         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
10185         log "LIMIT=$LIMIT"
10186         if [ $LIMIT -lt $LRU_SIZE ]; then
10187                 skip "Limit is too small $LIMIT"
10188         fi
10189
10190         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
10191         # killing locks. Some time was spent for creating locks. This means
10192         # that up to the moment of sleep finish we must have killed some of
10193         # them (10-100 locks). This depends on how fast ther were created.
10194         # Many of them were touched in almost the same moment and thus will
10195         # be killed in groups.
10196         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
10197
10198         # Use $LRU_SIZE_B here to take into account real number of locks
10199         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
10200         local LRU_SIZE_B=$LRU_SIZE
10201         log "LVF=$LVF"
10202         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
10203         log "OLD_LVF=$OLD_LVF"
10204         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
10205
10206         # Let's make sure that we really have some margin. Client checks
10207         # cached locks every 10 sec.
10208         SLEEP=$((SLEEP+20))
10209         log "Sleep ${SLEEP} sec"
10210         local SEC=0
10211         while ((SEC<$SLEEP)); do
10212                 echo -n "..."
10213                 sleep 5
10214                 SEC=$((SEC+5))
10215                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
10216                 echo -n "$LRU_SIZE"
10217         done
10218         echo ""
10219         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
10220         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
10221
10222         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
10223                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
10224                 unlinkmany $DIR/$tdir/f $NR
10225                 return
10226         }
10227
10228         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
10229         log "unlink $NR files at $DIR/$tdir"
10230         unlinkmany $DIR/$tdir/f $NR
10231 }
10232 run_test 124a "lru resize ======================================="
10233
10234 get_max_pool_limit()
10235 {
10236         local limit=$($LCTL get_param \
10237                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
10238         local max=0
10239         for l in $limit; do
10240                 if [[ $l -gt $max ]]; then
10241                         max=$l
10242                 fi
10243         done
10244         echo $max
10245 }
10246
10247 test_124b() {
10248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10249         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10250                 skip_env "no lru resize on server"
10251
10252         LIMIT=$(get_max_pool_limit)
10253
10254         NR=$(($(default_lru_size)*20))
10255         if [[ $NR -gt $LIMIT ]]; then
10256                 log "Limit lock number by $LIMIT locks"
10257                 NR=$LIMIT
10258         fi
10259
10260         IFree=$(mdsrate_inodes_available)
10261         if [ $IFree -lt $NR ]; then
10262                 log "Limit lock number by $IFree inodes"
10263                 NR=$IFree
10264         fi
10265
10266         lru_resize_disable mdc
10267         test_mkdir -p $DIR/$tdir/disable_lru_resize
10268
10269         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
10270         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
10271         cancel_lru_locks mdc
10272         stime=`date +%s`
10273         PID=""
10274         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10275         PID="$PID $!"
10276         sleep 2
10277         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10278         PID="$PID $!"
10279         sleep 2
10280         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10281         PID="$PID $!"
10282         wait $PID
10283         etime=`date +%s`
10284         nolruresize_delta=$((etime-stime))
10285         log "ls -la time: $nolruresize_delta seconds"
10286         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10287         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
10288
10289         lru_resize_enable mdc
10290         test_mkdir -p $DIR/$tdir/enable_lru_resize
10291
10292         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
10293         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
10294         cancel_lru_locks mdc
10295         stime=`date +%s`
10296         PID=""
10297         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10298         PID="$PID $!"
10299         sleep 2
10300         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10301         PID="$PID $!"
10302         sleep 2
10303         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10304         PID="$PID $!"
10305         wait $PID
10306         etime=`date +%s`
10307         lruresize_delta=$((etime-stime))
10308         log "ls -la time: $lruresize_delta seconds"
10309         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10310
10311         if [ $lruresize_delta -gt $nolruresize_delta ]; then
10312                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
10313         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
10314                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
10315         else
10316                 log "lru resize performs the same with no lru resize"
10317         fi
10318         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
10319 }
10320 run_test 124b "lru resize (performance test) ======================="
10321
10322 test_124c() {
10323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10324         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10325                 skip_env "no lru resize on server"
10326
10327         # cache ununsed locks on client
10328         local nr=100
10329         cancel_lru_locks mdc
10330         test_mkdir $DIR/$tdir
10331         createmany -o $DIR/$tdir/f $nr ||
10332                 error "failed to create $nr files in $DIR/$tdir"
10333         ls -l $DIR/$tdir > /dev/null
10334
10335         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
10336         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
10337         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
10338         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
10339         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
10340
10341         # set lru_max_age to 1 sec
10342         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
10343         echo "sleep $((recalc_p * 2)) seconds..."
10344         sleep $((recalc_p * 2))
10345
10346         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
10347         # restore lru_max_age
10348         $LCTL set_param -n $nsdir.lru_max_age $max_age
10349         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
10350         unlinkmany $DIR/$tdir/f $nr
10351 }
10352 run_test 124c "LRUR cancel very aged locks"
10353
10354 test_125() { # 13358
10355         $LCTL get_param -n llite.*.client_type | grep -q local ||
10356                 skip "must run as local client"
10357         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
10358                 skip_env "must have acl enabled"
10359         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
10360
10361         test_mkdir $DIR/$tdir
10362         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
10363         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
10364         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
10365 }
10366 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
10367
10368 test_126() { # bug 12829/13455
10369         $GSS && skip_env "must run as gss disabled"
10370         $LCTL get_param -n llite.*.client_type | grep -q local ||
10371                 skip "must run as local client"
10372         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
10373
10374         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
10375         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
10376         rm -f $DIR/$tfile
10377         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
10378 }
10379 run_test 126 "check that the fsgid provided by the client is taken into account"
10380
10381 test_127a() { # bug 15521
10382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10383
10384         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
10385         $LCTL set_param osc.*.stats=0
10386         FSIZE=$((2048 * 1024))
10387         dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
10388         cancel_lru_locks osc
10389         dd if=$DIR/$tfile of=/dev/null bs=$FSIZE
10390
10391         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/${tfile}.tmp
10392         while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
10393                 echo "got $COUNT $NAME"
10394                 [ ! $MIN ] && error "Missing min value for $NAME proc entry"
10395                 eval $NAME=$COUNT || error "Wrong proc format"
10396
10397                 case $NAME in
10398                         read_bytes|write_bytes)
10399                         [ $MIN -lt 4096 ] && error "min is too small: $MIN"
10400                         [ $MIN -gt $FSIZE ] && error "min is too big: $MIN"
10401                         [ $MAX -lt 4096 ] && error "max is too small: $MAX"
10402                         [ $MAX -gt $FSIZE ] && error "max is too big: $MAX"
10403                         [ $SUM -ne $FSIZE ] && error "sum is wrong: $SUM"
10404                         [ $SUMSQ -lt $(((FSIZE /4096) * (4096 * 4096))) ] &&
10405                                 error "sumsquare is too small: $SUMSQ"
10406                         [ $SUMSQ -gt $((FSIZE * FSIZE)) ] &&
10407                                 error "sumsquare is too big: $SUMSQ"
10408                         ;;
10409                         *) ;;
10410                 esac
10411         done < $DIR/${tfile}.tmp
10412
10413         #check that we actually got some stats
10414         [ "$read_bytes" ] || error "Missing read_bytes stats"
10415         [ "$write_bytes" ] || error "Missing write_bytes stats"
10416         [ "$read_bytes" != 0 ] || error "no read done"
10417         [ "$write_bytes" != 0 ] || error "no write done"
10418 }
10419 run_test 127a "verify the client stats are sane"
10420
10421 test_127b() { # bug LU-333
10422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10423         local name count samp unit min max sum sumsq
10424
10425         $LCTL set_param llite.*.stats=0
10426
10427         # perform 2 reads and writes so MAX is different from SUM.
10428         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10429         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10430         cancel_lru_locks osc
10431         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10432         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10433
10434         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
10435         while read name count samp unit min max sum sumsq; do
10436                 echo "got $count $name"
10437                 eval $name=$count || error "Wrong proc format"
10438
10439                 case $name in
10440                 read_bytes)
10441                         [ $count -ne 2 ] && error "count is not 2: $count"
10442                         [ $min -ne $PAGE_SIZE ] &&
10443                                 error "min is not $PAGE_SIZE: $min"
10444                         [ $max -ne $PAGE_SIZE ] &&
10445                                 error "max is incorrect: $max"
10446                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10447                                 error "sum is wrong: $sum"
10448                         ;;
10449                 write_bytes)
10450                         [ $count -ne 2 ] && error "count is not 2: $count"
10451                         [ $min -ne $PAGE_SIZE ] &&
10452                                 error "min is not $PAGE_SIZE: $min"
10453                         [ $max -ne $PAGE_SIZE ] &&
10454                                 error "max is incorrect: $max"
10455                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10456                                 error "sum is wrong: $sum"
10457                         ;;
10458                 *) ;;
10459                 esac
10460         done < $TMP/$tfile.tmp
10461
10462         #check that we actually got some stats
10463         [ "$read_bytes" ] || error "Missing read_bytes stats"
10464         [ "$write_bytes" ] || error "Missing write_bytes stats"
10465         [ "$read_bytes" != 0 ] || error "no read done"
10466         [ "$write_bytes" != 0 ] || error "no write done"
10467
10468         rm -f $TMP/${tfile}.tmp
10469 }
10470 run_test 127b "verify the llite client stats are sane"
10471
10472 test_128() { # bug 15212
10473         touch $DIR/$tfile
10474         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
10475                 find $DIR/$tfile
10476                 find $DIR/$tfile
10477         EOF
10478
10479         result=$(grep error $TMP/$tfile.log)
10480         rm -f $DIR/$tfile $TMP/$tfile.log
10481         [ -z "$result" ] ||
10482                 error "consecutive find's under interactive lfs failed"
10483 }
10484 run_test 128 "interactive lfs for 2 consecutive find's"
10485
10486 set_dir_limits () {
10487         local mntdev
10488         local canondev
10489         local node
10490
10491         local ldproc=/proc/fs/ldiskfs
10492         local facets=$(get_facets MDS)
10493
10494         for facet in ${facets//,/ }; do
10495                 canondev=$(ldiskfs_canon \
10496                            *.$(convert_facet2label $facet).mntdev $facet)
10497                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
10498                         ldproc=/sys/fs/ldiskfs
10499                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
10500                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
10501         done
10502 }
10503
10504 check_mds_dmesg() {
10505         local facets=$(get_facets MDS)
10506         for facet in ${facets//,/ }; do
10507                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
10508         done
10509         return 1
10510 }
10511
10512 test_129() {
10513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10514         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
10515                 skip "Need MDS version with at least 2.5.56"
10516         if [ "$mds1_FSTYPE" != ldiskfs ]; then
10517                 skip_env "ldiskfs only test"
10518         fi
10519         remote_mds_nodsh && skip "remote MDS with nodsh"
10520
10521         local ENOSPC=28
10522         local EFBIG=27
10523         local has_warning=false
10524
10525         rm -rf $DIR/$tdir
10526         mkdir -p $DIR/$tdir
10527
10528         # block size of mds1
10529         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
10530         set_dir_limits $maxsize $maxsize
10531         local dirsize=$(stat -c%s "$DIR/$tdir")
10532         local nfiles=0
10533         while [[ $dirsize -le $maxsize ]]; do
10534                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
10535                 rc=$?
10536                 if ! $has_warning; then
10537                         check_mds_dmesg '"is approaching"' && has_warning=true
10538                 fi
10539                 # check two errors:
10540                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
10541                 # EFBIG for previous versions included in ldiskfs series
10542                 if [ $rc -eq $EFBIG ] || [ $rc -eq $ENOSPC ]; then
10543                         set_dir_limits 0 0
10544                         echo "return code $rc received as expected"
10545
10546                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
10547                                 error_exit "create failed w/o dir size limit"
10548
10549                         check_mds_dmesg '"has reached"' ||
10550                                 error_exit "reached message should be output"
10551
10552                         [ $has_warning = "false" ] &&
10553                                 error_exit "warning message should be output"
10554
10555                         dirsize=$(stat -c%s "$DIR/$tdir")
10556
10557                         [[ $dirsize -ge $maxsize ]] && return 0
10558                         error_exit "current dir size $dirsize, " \
10559                                    "previous limit $maxsize"
10560                 elif [ $rc -ne 0 ]; then
10561                         set_dir_limits 0 0
10562                         error_exit "return $rc received instead of expected " \
10563                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
10564                 fi
10565                 nfiles=$((nfiles + 1))
10566                 dirsize=$(stat -c%s "$DIR/$tdir")
10567         done
10568
10569         set_dir_limits 0 0
10570         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
10571 }
10572 run_test 129 "test directory size limit ========================"
10573
10574 OLDIFS="$IFS"
10575 cleanup_130() {
10576         trap 0
10577         IFS="$OLDIFS"
10578 }
10579
10580 test_130a() {
10581         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10582         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10583
10584         trap cleanup_130 EXIT RETURN
10585
10586         local fm_file=$DIR/$tfile
10587         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
10588         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
10589                 error "dd failed for $fm_file"
10590
10591         # LU-1795: test filefrag/FIEMAP once, even if unsupported
10592         filefrag -ves $fm_file
10593         RC=$?
10594         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10595                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10596         [ $RC != 0 ] && error "filefrag $fm_file failed"
10597
10598         filefrag_op=$(filefrag -ve -k $fm_file |
10599                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10600         lun=$($LFS getstripe -i $fm_file)
10601
10602         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
10603         IFS=$'\n'
10604         tot_len=0
10605         for line in $filefrag_op
10606         do
10607                 frag_lun=`echo $line | cut -d: -f5`
10608                 ext_len=`echo $line | cut -d: -f4`
10609                 if (( $frag_lun != $lun )); then
10610                         cleanup_130
10611                         error "FIEMAP on 1-stripe file($fm_file) failed"
10612                         return
10613                 fi
10614                 (( tot_len += ext_len ))
10615         done
10616
10617         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
10618                 cleanup_130
10619                 error "FIEMAP on 1-stripe file($fm_file) failed;"
10620                 return
10621         fi
10622
10623         cleanup_130
10624
10625         echo "FIEMAP on single striped file succeeded"
10626 }
10627 run_test 130a "FIEMAP (1-stripe file)"
10628
10629 test_130b() {
10630         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
10631
10632         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10633         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10634
10635         trap cleanup_130 EXIT RETURN
10636
10637         local fm_file=$DIR/$tfile
10638         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
10639                         error "setstripe on $fm_file"
10640         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10641                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10642
10643         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
10644                 error "dd failed on $fm_file"
10645
10646         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10647         filefrag_op=$(filefrag -ve -k $fm_file |
10648                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10649
10650         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10651                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10652
10653         IFS=$'\n'
10654         tot_len=0
10655         num_luns=1
10656         for line in $filefrag_op
10657         do
10658                 frag_lun=$(echo $line | cut -d: -f5 |
10659                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10660                 ext_len=$(echo $line | cut -d: -f4)
10661                 if (( $frag_lun != $last_lun )); then
10662                         if (( tot_len != 1024 )); then
10663                                 cleanup_130
10664                                 error "FIEMAP on $fm_file failed; returned " \
10665                                 "len $tot_len for OST $last_lun instead of 1024"
10666                                 return
10667                         else
10668                                 (( num_luns += 1 ))
10669                                 tot_len=0
10670                         fi
10671                 fi
10672                 (( tot_len += ext_len ))
10673                 last_lun=$frag_lun
10674         done
10675         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
10676                 cleanup_130
10677                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10678                         "luns or wrong len for OST $last_lun"
10679                 return
10680         fi
10681
10682         cleanup_130
10683
10684         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
10685 }
10686 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
10687
10688 test_130c() {
10689         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10690
10691         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10692         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10693
10694         trap cleanup_130 EXIT RETURN
10695
10696         local fm_file=$DIR/$tfile
10697         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
10698         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10699                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10700
10701         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
10702                         error "dd failed on $fm_file"
10703
10704         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10705         filefrag_op=$(filefrag -ve -k $fm_file |
10706                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10707
10708         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10709                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10710
10711         IFS=$'\n'
10712         tot_len=0
10713         num_luns=1
10714         for line in $filefrag_op
10715         do
10716                 frag_lun=$(echo $line | cut -d: -f5 |
10717                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10718                 ext_len=$(echo $line | cut -d: -f4)
10719                 if (( $frag_lun != $last_lun )); then
10720                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
10721                         if (( logical != 512 )); then
10722                                 cleanup_130
10723                                 error "FIEMAP on $fm_file failed; returned " \
10724                                 "logical start for lun $logical instead of 512"
10725                                 return
10726                         fi
10727                         if (( tot_len != 512 )); then
10728                                 cleanup_130
10729                                 error "FIEMAP on $fm_file failed; returned " \
10730                                 "len $tot_len for OST $last_lun instead of 1024"
10731                                 return
10732                         else
10733                                 (( num_luns += 1 ))
10734                                 tot_len=0
10735                         fi
10736                 fi
10737                 (( tot_len += ext_len ))
10738                 last_lun=$frag_lun
10739         done
10740         if (( num_luns != 2 || tot_len != 512 )); then
10741                 cleanup_130
10742                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10743                         "luns or wrong len for OST $last_lun"
10744                 return
10745         fi
10746
10747         cleanup_130
10748
10749         echo "FIEMAP on 2-stripe file with hole succeeded"
10750 }
10751 run_test 130c "FIEMAP (2-stripe file with hole)"
10752
10753 test_130d() {
10754         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
10755
10756         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10757         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10758
10759         trap cleanup_130 EXIT RETURN
10760
10761         local fm_file=$DIR/$tfile
10762         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
10763                         error "setstripe on $fm_file"
10764         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10765                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10766
10767         local actual_stripe_count=$($LFS getstripe -c $fm_file)
10768         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
10769                 error "dd failed on $fm_file"
10770
10771         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10772         filefrag_op=$(filefrag -ve -k $fm_file |
10773                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10774
10775         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10776                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10777
10778         IFS=$'\n'
10779         tot_len=0
10780         num_luns=1
10781         for line in $filefrag_op
10782         do
10783                 frag_lun=$(echo $line | cut -d: -f5 |
10784                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10785                 ext_len=$(echo $line | cut -d: -f4)
10786                 if (( $frag_lun != $last_lun )); then
10787                         if (( tot_len != 1024 )); then
10788                                 cleanup_130
10789                                 error "FIEMAP on $fm_file failed; returned " \
10790                                 "len $tot_len for OST $last_lun instead of 1024"
10791                                 return
10792                         else
10793                                 (( num_luns += 1 ))
10794                                 tot_len=0
10795                         fi
10796                 fi
10797                 (( tot_len += ext_len ))
10798                 last_lun=$frag_lun
10799         done
10800         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
10801                 cleanup_130
10802                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10803                         "luns or wrong len for OST $last_lun"
10804                 return
10805         fi
10806
10807         cleanup_130
10808
10809         echo "FIEMAP on N-stripe file succeeded"
10810 }
10811 run_test 130d "FIEMAP (N-stripe file)"
10812
10813 test_130e() {
10814         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10815
10816         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10817         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10818
10819         trap cleanup_130 EXIT RETURN
10820
10821         local fm_file=$DIR/$tfile
10822         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
10823         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10824                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10825
10826         NUM_BLKS=512
10827         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
10828         for ((i = 0; i < $NUM_BLKS; i++))
10829         do
10830                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
10831         done
10832
10833         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10834         filefrag_op=$(filefrag -ve -k $fm_file |
10835                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10836
10837         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10838                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10839
10840         IFS=$'\n'
10841         tot_len=0
10842         num_luns=1
10843         for line in $filefrag_op
10844         do
10845                 frag_lun=$(echo $line | cut -d: -f5 |
10846                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10847                 ext_len=$(echo $line | cut -d: -f4)
10848                 if (( $frag_lun != $last_lun )); then
10849                         if (( tot_len != $EXPECTED_LEN )); then
10850                                 cleanup_130
10851                                 error "FIEMAP on $fm_file failed; returned " \
10852                                 "len $tot_len for OST $last_lun instead " \
10853                                 "of $EXPECTED_LEN"
10854                                 return
10855                         else
10856                                 (( num_luns += 1 ))
10857                                 tot_len=0
10858                         fi
10859                 fi
10860                 (( tot_len += ext_len ))
10861                 last_lun=$frag_lun
10862         done
10863         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
10864                 cleanup_130
10865                 error "FIEMAP on $fm_file failed; returned wrong number " \
10866                         "of luns or wrong len for OST $last_lun"
10867                 return
10868         fi
10869
10870         cleanup_130
10871
10872         echo "FIEMAP with continuation calls succeeded"
10873 }
10874 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
10875
10876 test_130f() {
10877         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10878         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10879
10880         local fm_file=$DIR/$tfile
10881         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
10882                 error "multiop create with lov_delay_create on $fm_file"
10883
10884         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10885         filefrag_extents=$(filefrag -vek $fm_file |
10886                            awk '/extents? found/ { print $2 }')
10887         if [[ "$filefrag_extents" != "0" ]]; then
10888                 error "FIEMAP on $fm_file failed; " \
10889                       "returned $filefrag_extents expected 0"
10890         fi
10891
10892         rm -f $fm_file
10893 }
10894 run_test 130f "FIEMAP (unstriped file)"
10895
10896 # Test for writev/readv
10897 test_131a() {
10898         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
10899                 error "writev test failed"
10900         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
10901                 error "readv failed"
10902         rm -f $DIR/$tfile
10903 }
10904 run_test 131a "test iov's crossing stripe boundary for writev/readv"
10905
10906 test_131b() {
10907         local fsize=$((524288 + 1048576 + 1572864))
10908         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
10909                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
10910                         error "append writev test failed"
10911
10912         ((fsize += 1572864 + 1048576))
10913         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
10914                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
10915                         error "append writev test failed"
10916         rm -f $DIR/$tfile
10917 }
10918 run_test 131b "test append writev"
10919
10920 test_131c() {
10921         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
10922         error "NOT PASS"
10923 }
10924 run_test 131c "test read/write on file w/o objects"
10925
10926 test_131d() {
10927         rwv -f $DIR/$tfile -w -n 1 1572864
10928         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
10929         if [ "$NOB" != 1572864 ]; then
10930                 error "Short read filed: read $NOB bytes instead of 1572864"
10931         fi
10932         rm -f $DIR/$tfile
10933 }
10934 run_test 131d "test short read"
10935
10936 test_131e() {
10937         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
10938         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
10939         error "read hitting hole failed"
10940         rm -f $DIR/$tfile
10941 }
10942 run_test 131e "test read hitting hole"
10943
10944 check_stats() {
10945         local facet=$1
10946         local op=$2
10947         local want=${3:-0}
10948         local res
10949
10950         case $facet in
10951         mds*) res=$(do_facet $facet \
10952                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
10953                  ;;
10954         ost*) res=$(do_facet $facet \
10955                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
10956                  ;;
10957         *) error "Wrong facet '$facet'" ;;
10958         esac
10959         [ "$res" ] || error "The counter for $op on $facet was not incremented"
10960         # if the argument $3 is zero, it means any stat increment is ok.
10961         if [[ $want -gt 0 ]]; then
10962                 local count=$(echo $res | awk '{ print $2 }')
10963                 [[ $count -ne $want ]] &&
10964                         error "The $op counter on $facet is $count, not $want"
10965         fi
10966 }
10967
10968 test_133a() {
10969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10970         remote_ost_nodsh && skip "remote OST with nodsh"
10971         remote_mds_nodsh && skip "remote MDS with nodsh"
10972         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
10973                 skip_env "MDS doesn't support rename stats"
10974
10975         local testdir=$DIR/${tdir}/stats_testdir
10976
10977         mkdir -p $DIR/${tdir}
10978
10979         # clear stats.
10980         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
10981         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
10982
10983         # verify mdt stats first.
10984         mkdir ${testdir} || error "mkdir failed"
10985         check_stats $SINGLEMDS "mkdir" 1
10986         touch ${testdir}/${tfile} || error "touch failed"
10987         check_stats $SINGLEMDS "open" 1
10988         check_stats $SINGLEMDS "close" 1
10989         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
10990                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
10991                 check_stats $SINGLEMDS "mknod" 2
10992         }
10993         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
10994         check_stats $SINGLEMDS "unlink" 1
10995         rm -f ${testdir}/${tfile} || error "file remove failed"
10996         check_stats $SINGLEMDS "unlink" 2
10997
10998         # remove working dir and check mdt stats again.
10999         rmdir ${testdir} || error "rmdir failed"
11000         check_stats $SINGLEMDS "rmdir" 1
11001
11002         local testdir1=$DIR/${tdir}/stats_testdir1
11003         mkdir -p ${testdir}
11004         mkdir -p ${testdir1}
11005         touch ${testdir1}/test1
11006         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
11007         check_stats $SINGLEMDS "crossdir_rename" 1
11008
11009         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
11010         check_stats $SINGLEMDS "samedir_rename" 1
11011
11012         rm -rf $DIR/${tdir}
11013 }
11014 run_test 133a "Verifying MDT stats ========================================"
11015
11016 test_133b() {
11017         local res
11018
11019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11020         remote_ost_nodsh && skip "remote OST with nodsh"
11021         remote_mds_nodsh && skip "remote MDS with nodsh"
11022
11023         local testdir=$DIR/${tdir}/stats_testdir
11024
11025         mkdir -p ${testdir} || error "mkdir failed"
11026         touch ${testdir}/${tfile} || error "touch failed"
11027         cancel_lru_locks mdc
11028
11029         # clear stats.
11030         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11031         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11032
11033         # extra mdt stats verification.
11034         chmod 444 ${testdir}/${tfile} || error "chmod failed"
11035         check_stats $SINGLEMDS "setattr" 1
11036         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11037         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
11038         then            # LU-1740
11039                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
11040                 check_stats $SINGLEMDS "getattr" 1
11041         fi
11042         rm -rf $DIR/${tdir}
11043
11044         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
11045         # so the check below is not reliable
11046         [ $MDSCOUNT -eq 1 ] || return 0
11047
11048         # Sleep to avoid a cached response.
11049         #define OBD_STATFS_CACHE_SECONDS 1
11050         sleep 2
11051         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11052         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11053         $LFS df || error "lfs failed"
11054         check_stats $SINGLEMDS "statfs" 1
11055
11056         # check aggregated statfs (LU-10018)
11057         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
11058                 return 0
11059         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
11060                 return 0
11061         sleep 2
11062         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11063         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11064         df $DIR
11065         check_stats $SINGLEMDS "statfs" 1
11066
11067         # We want to check that the client didn't send OST_STATFS to
11068         # ost1 but the MDT also uses OST_STATFS for precreate. So some
11069         # extra care is needed here.
11070         if remote_mds; then
11071                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
11072                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
11073
11074                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
11075                 [ "$res" ] && error "OST got STATFS"
11076         fi
11077
11078         return 0
11079 }
11080 run_test 133b "Verifying extra MDT stats =================================="
11081
11082 test_133c() {
11083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11084         remote_ost_nodsh && skip "remote OST with nodsh"
11085         remote_mds_nodsh && skip "remote MDS with nodsh"
11086
11087         local testdir=$DIR/$tdir/stats_testdir
11088
11089         test_mkdir -p $testdir
11090
11091         # verify obdfilter stats.
11092         $LFS setstripe -c 1 -i 0 $testdir/$tfile
11093         sync
11094         cancel_lru_locks osc
11095         wait_delete_completed
11096
11097         # clear stats.
11098         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11099         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11100
11101         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
11102                 error "dd failed"
11103         sync
11104         cancel_lru_locks osc
11105         check_stats ost1 "write" 1
11106
11107         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
11108         check_stats ost1 "read" 1
11109
11110         > $testdir/$tfile || error "truncate failed"
11111         check_stats ost1 "punch" 1
11112
11113         rm -f $testdir/$tfile || error "file remove failed"
11114         wait_delete_completed
11115         check_stats ost1 "destroy" 1
11116
11117         rm -rf $DIR/$tdir
11118 }
11119 run_test 133c "Verifying OST stats ========================================"
11120
11121 order_2() {
11122         local value=$1
11123         local orig=$value
11124         local order=1
11125
11126         while [ $value -ge 2 ]; do
11127                 order=$((order*2))
11128                 value=$((value/2))
11129         done
11130
11131         if [ $orig -gt $order ]; then
11132                 order=$((order*2))
11133         fi
11134         echo $order
11135 }
11136
11137 size_in_KMGT() {
11138     local value=$1
11139     local size=('K' 'M' 'G' 'T');
11140     local i=0
11141     local size_string=$value
11142
11143     while [ $value -ge 1024 ]; do
11144         if [ $i -gt 3 ]; then
11145             #T is the biggest unit we get here, if that is bigger,
11146             #just return XXXT
11147             size_string=${value}T
11148             break
11149         fi
11150         value=$((value >> 10))
11151         if [ $value -lt 1024 ]; then
11152             size_string=${value}${size[$i]}
11153             break
11154         fi
11155         i=$((i + 1))
11156     done
11157
11158     echo $size_string
11159 }
11160
11161 get_rename_size() {
11162         local size=$1
11163         local context=${2:-.}
11164         local sample=$(do_facet $SINGLEMDS $LCTL \
11165                 get_param mdt.$FSNAME-MDT0000.rename_stats |
11166                 grep -A1 $context |
11167                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
11168         echo $sample
11169 }
11170
11171 test_133d() {
11172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11173         remote_ost_nodsh && skip "remote OST with nodsh"
11174         remote_mds_nodsh && skip "remote MDS with nodsh"
11175         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11176                 skip_env "MDS doesn't support rename stats"
11177
11178         local testdir1=$DIR/${tdir}/stats_testdir1
11179         local testdir2=$DIR/${tdir}/stats_testdir2
11180         mkdir -p $DIR/${tdir}
11181
11182         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11183
11184         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
11185         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
11186
11187         createmany -o $testdir1/test 512 || error "createmany failed"
11188
11189         # check samedir rename size
11190         mv ${testdir1}/test0 ${testdir1}/test_0
11191
11192         local testdir1_size=$(ls -l $DIR/${tdir} |
11193                 awk '/stats_testdir1/ {print $5}')
11194         local testdir2_size=$(ls -l $DIR/${tdir} |
11195                 awk '/stats_testdir2/ {print $5}')
11196
11197         testdir1_size=$(order_2 $testdir1_size)
11198         testdir2_size=$(order_2 $testdir2_size)
11199
11200         testdir1_size=$(size_in_KMGT $testdir1_size)
11201         testdir2_size=$(size_in_KMGT $testdir2_size)
11202
11203         echo "source rename dir size: ${testdir1_size}"
11204         echo "target rename dir size: ${testdir2_size}"
11205
11206         local cmd="do_facet $SINGLEMDS $LCTL "
11207         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
11208
11209         eval $cmd || error "$cmd failed"
11210         local samedir=$($cmd | grep 'same_dir')
11211         local same_sample=$(get_rename_size $testdir1_size)
11212         [ -z "$samedir" ] && error "samedir_rename_size count error"
11213         [[ $same_sample -eq 1 ]] ||
11214                 error "samedir_rename_size error $same_sample"
11215         echo "Check same dir rename stats success"
11216
11217         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11218
11219         # check crossdir rename size
11220         mv ${testdir1}/test_0 ${testdir2}/test_0
11221
11222         testdir1_size=$(ls -l $DIR/${tdir} |
11223                 awk '/stats_testdir1/ {print $5}')
11224         testdir2_size=$(ls -l $DIR/${tdir} |
11225                 awk '/stats_testdir2/ {print $5}')
11226
11227         testdir1_size=$(order_2 $testdir1_size)
11228         testdir2_size=$(order_2 $testdir2_size)
11229
11230         testdir1_size=$(size_in_KMGT $testdir1_size)
11231         testdir2_size=$(size_in_KMGT $testdir2_size)
11232
11233         echo "source rename dir size: ${testdir1_size}"
11234         echo "target rename dir size: ${testdir2_size}"
11235
11236         eval $cmd || error "$cmd failed"
11237         local crossdir=$($cmd | grep 'crossdir')
11238         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
11239         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
11240         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
11241         [[ $src_sample -eq 1 ]] ||
11242                 error "crossdir_rename_size error $src_sample"
11243         [[ $tgt_sample -eq 1 ]] ||
11244                 error "crossdir_rename_size error $tgt_sample"
11245         echo "Check cross dir rename stats success"
11246         rm -rf $DIR/${tdir}
11247 }
11248 run_test 133d "Verifying rename_stats ========================================"
11249
11250 test_133e() {
11251         remote_mds_nodsh && skip "remote MDS with nodsh"
11252         remote_ost_nodsh && skip "remote OST with nodsh"
11253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11254
11255         local testdir=$DIR/${tdir}/stats_testdir
11256         local ctr f0 f1 bs=32768 count=42 sum
11257
11258         mkdir -p ${testdir} || error "mkdir failed"
11259
11260         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
11261
11262         for ctr in {write,read}_bytes; do
11263                 sync
11264                 cancel_lru_locks osc
11265
11266                 do_facet ost1 $LCTL set_param -n \
11267                         "obdfilter.*.exports.clear=clear"
11268
11269                 if [ $ctr = write_bytes ]; then
11270                         f0=/dev/zero
11271                         f1=${testdir}/${tfile}
11272                 else
11273                         f0=${testdir}/${tfile}
11274                         f1=/dev/null
11275                 fi
11276
11277                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
11278                         error "dd failed"
11279                 sync
11280                 cancel_lru_locks osc
11281
11282                 sum=$(do_facet ost1 $LCTL get_param \
11283                         "obdfilter.*.exports.*.stats" |
11284                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
11285                                 $1 == ctr { sum += $7 }
11286                                 END { printf("%0.0f", sum) }')
11287
11288                 if ((sum != bs * count)); then
11289                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
11290                 fi
11291         done
11292
11293         rm -rf $DIR/${tdir}
11294 }
11295 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
11296
11297 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
11298
11299 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
11300 # not honor the -ignore_readdir_race option correctly. So we call
11301 # error_ignore() rather than error() in these cases. See LU-11152.
11302 error_133() {
11303         if (find --version; do_facet mds1 find --version) |
11304                 grep -q '\b4\.5\.1[1-4]\b'; then
11305                 error_ignore LU-11152 "$@"
11306         else
11307                 error "$@"
11308         fi
11309 }
11310
11311 test_133f() {
11312         # First without trusting modes.
11313         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
11314         echo "proc_dirs='$proc_dirs'"
11315         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
11316         find $proc_dirs -exec cat '{}' \; &> /dev/null
11317
11318         # Second verifying readability.
11319         $LCTL get_param -R '*' &> /dev/null
11320
11321         # Verifing writability with badarea_io.
11322         find $proc_dirs \
11323                 -ignore_readdir_race \
11324                 -type f \
11325                 -not -name force_lbug \
11326                 -not -name changelog_mask \
11327                 -exec badarea_io '{}' \; ||
11328                         error_133 "find $proc_dirs failed"
11329 }
11330 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
11331
11332 test_133g() {
11333         remote_mds_nodsh && skip "remote MDS with nodsh"
11334         remote_ost_nodsh && skip "remote OST with nodsh"
11335
11336         # eventually, this can also be replaced with "lctl get_param -R",
11337         # but not until that option is always available on the server
11338         local facet
11339         for facet in mds1 ost1; do
11340                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
11341                         skip_noexit "Too old lustre on $facet"
11342                 local facet_proc_dirs=$(do_facet $facet \
11343                                         \\\ls -d $proc_regexp 2>/dev/null)
11344                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11345                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11346                 do_facet $facet find $facet_proc_dirs \
11347                         ! -name req_history \
11348                         -exec cat '{}' \\\; &> /dev/null
11349
11350                 do_facet $facet find $facet_proc_dirs \
11351                         ! -name req_history \
11352                         -type f \
11353                         -exec cat '{}' \\\; &> /dev/null ||
11354                                 error "proc file read failed"
11355
11356                 do_facet $facet find $facet_proc_dirs \
11357                         -ignore_readdir_race \
11358                         -type f \
11359                         -not -name force_lbug \
11360                         -not -name changelog_mask \
11361                         -exec badarea_io '{}' \\\; ||
11362                                 error_133 "$facet find $facet_proc_dirs failed"
11363         done
11364
11365         # remount the FS in case writes/reads /proc break the FS
11366         cleanup || error "failed to unmount"
11367         setup || error "failed to setup"
11368         true
11369 }
11370 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
11371
11372 test_133h() {
11373         remote_mds_nodsh && skip "remote MDS with nodsh"
11374         remote_ost_nodsh && skip "remote OST with nodsh"
11375         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
11376                 skip "Need MDS version at least 2.9.54"
11377
11378         local facet
11379
11380         for facet in client mds1 ost1; do
11381                 local facet_proc_dirs=$(do_facet $facet \
11382                                         \\\ls -d $proc_regexp 2> /dev/null)
11383                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11384                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11385                 # Get the list of files that are missing the terminating newline
11386                 local missing=($(do_facet $facet \
11387                         find ${facet_proc_dirs} -type f \|              \
11388                                 while read F\; do                       \
11389                                         awk -v FS='\v' -v RS='\v\v'     \
11390                                         "'END { if(NR>0 &&              \
11391                                         \\\$NF !~ /.*\\\n\$/)           \
11392                                                 print FILENAME}'"       \
11393                                         '\$F'\;                         \
11394                                 done 2>/dev/null))
11395                 [ ${#missing[*]} -eq 0 ] ||
11396                         error "files do not end with newline: ${missing[*]}"
11397         done
11398 }
11399 run_test 133h "Proc files should end with newlines"
11400
11401 test_134a() {
11402         remote_mds_nodsh && skip "remote MDS with nodsh"
11403         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11404                 skip "Need MDS version at least 2.7.54"
11405
11406         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11407         cancel_lru_locks mdc
11408
11409         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11410         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11411         [ $unused -eq 0 ] || error "$unused locks are not cleared"
11412
11413         local nr=1000
11414         createmany -o $DIR/$tdir/f $nr ||
11415                 error "failed to create $nr files in $DIR/$tdir"
11416         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11417
11418         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
11419         do_facet mds1 $LCTL set_param fail_loc=0x327
11420         do_facet mds1 $LCTL set_param fail_val=500
11421         touch $DIR/$tdir/m
11422
11423         echo "sleep 10 seconds ..."
11424         sleep 10
11425         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
11426
11427         do_facet mds1 $LCTL set_param fail_loc=0
11428         do_facet mds1 $LCTL set_param fail_val=0
11429         [ $lck_cnt -lt $unused ] ||
11430                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
11431
11432         rm $DIR/$tdir/m
11433         unlinkmany $DIR/$tdir/f $nr
11434 }
11435 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
11436
11437 test_134b() {
11438         remote_mds_nodsh && skip "remote MDS with nodsh"
11439         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11440                 skip "Need MDS version at least 2.7.54"
11441
11442         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11443         cancel_lru_locks mdc
11444
11445         local low_wm=$(do_facet mds1 $LCTL get_param -n \
11446                         ldlm.lock_reclaim_threshold_mb)
11447         # disable reclaim temporarily
11448         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
11449
11450         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
11451         do_facet mds1 $LCTL set_param fail_loc=0x328
11452         do_facet mds1 $LCTL set_param fail_val=500
11453
11454         $LCTL set_param debug=+trace
11455
11456         local nr=600
11457         createmany -o $DIR/$tdir/f $nr &
11458         local create_pid=$!
11459
11460         echo "Sleep $TIMEOUT seconds ..."
11461         sleep $TIMEOUT
11462         if ! ps -p $create_pid  > /dev/null 2>&1; then
11463                 do_facet mds1 $LCTL set_param fail_loc=0
11464                 do_facet mds1 $LCTL set_param fail_val=0
11465                 do_facet mds1 $LCTL set_param \
11466                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
11467                 error "createmany finished incorrectly!"
11468         fi
11469         do_facet mds1 $LCTL set_param fail_loc=0
11470         do_facet mds1 $LCTL set_param fail_val=0
11471         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
11472         wait $create_pid || return 1
11473
11474         unlinkmany $DIR/$tdir/f $nr
11475 }
11476 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
11477
11478 test_140() { #bug-17379
11479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11480
11481         test_mkdir $DIR/$tdir
11482         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
11483         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
11484
11485         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
11486         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
11487         local i=0
11488         while i=$((i + 1)); do
11489                 test_mkdir $i
11490                 cd $i || error "Changing to $i"
11491                 ln -s ../stat stat || error "Creating stat symlink"
11492                 # Read the symlink until ELOOP present,
11493                 # not LBUGing the system is considered success,
11494                 # we didn't overrun the stack.
11495                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
11496                 if [ $ret -ne 0 ]; then
11497                         if [ $ret -eq 40 ]; then
11498                                 break  # -ELOOP
11499                         else
11500                                 error "Open stat symlink"
11501                                         return
11502                         fi
11503                 fi
11504         done
11505         i=$((i - 1))
11506         echo "The symlink depth = $i"
11507         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
11508                 error "Invalid symlink depth"
11509
11510         # Test recursive symlink
11511         ln -s symlink_self symlink_self
11512         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
11513         echo "open symlink_self returns $ret"
11514         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
11515 }
11516 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
11517
11518 test_150() {
11519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11520
11521         local TF="$TMP/$tfile"
11522
11523         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
11524         cp $TF $DIR/$tfile
11525         cancel_lru_locks $OSC
11526         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
11527         remount_client $MOUNT
11528         df -P $MOUNT
11529         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
11530
11531         $TRUNCATE $TF 6000
11532         $TRUNCATE $DIR/$tfile 6000
11533         cancel_lru_locks $OSC
11534         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
11535
11536         echo "12345" >>$TF
11537         echo "12345" >>$DIR/$tfile
11538         cancel_lru_locks $OSC
11539         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
11540
11541         echo "12345" >>$TF
11542         echo "12345" >>$DIR/$tfile
11543         cancel_lru_locks $OSC
11544         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
11545
11546         rm -f $TF
11547         true
11548 }
11549 run_test 150 "truncate/append tests"
11550
11551 #LU-2902 roc_hit was not able to read all values from lproc
11552 function roc_hit_init() {
11553         local list=$(comma_list $(osts_nodes))
11554         local dir=$DIR/$tdir-check
11555         local file=$dir/$tfile
11556         local BEFORE
11557         local AFTER
11558         local idx
11559
11560         test_mkdir $dir
11561         #use setstripe to do a write to every ost
11562         for i in $(seq 0 $((OSTCOUNT-1))); do
11563                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
11564                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
11565                 idx=$(printf %04x $i)
11566                 BEFORE=$(get_osd_param $list *OST*$idx stats |
11567                         awk '$1 == "cache_access" {sum += $7}
11568                                 END { printf("%0.0f", sum) }')
11569
11570                 cancel_lru_locks osc
11571                 cat $file >/dev/null
11572
11573                 AFTER=$(get_osd_param $list *OST*$idx stats |
11574                         awk '$1 == "cache_access" {sum += $7}
11575                                 END { printf("%0.0f", sum) }')
11576
11577                 echo BEFORE:$BEFORE AFTER:$AFTER
11578                 if ! let "AFTER - BEFORE == 4"; then
11579                         rm -rf $dir
11580                         error "roc_hit is not safe to use"
11581                 fi
11582                 rm $file
11583         done
11584
11585         rm -rf $dir
11586 }
11587
11588 function roc_hit() {
11589         local list=$(comma_list $(osts_nodes))
11590         echo $(get_osd_param $list '' stats |
11591                 awk '$1 == "cache_hit" {sum += $7}
11592                         END { printf("%0.0f", sum) }')
11593 }
11594
11595 function set_cache() {
11596         local on=1
11597
11598         if [ "$2" == "off" ]; then
11599                 on=0;
11600         fi
11601         local list=$(comma_list $(osts_nodes))
11602         set_osd_param $list '' $1_cache_enable $on
11603
11604         cancel_lru_locks osc
11605 }
11606
11607 test_151() {
11608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11609         remote_ost_nodsh && skip "remote OST with nodsh"
11610
11611         local CPAGES=3
11612         local list=$(comma_list $(osts_nodes))
11613
11614         # check whether obdfilter is cache capable at all
11615         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
11616                 skip "not cache-capable obdfilter"
11617         fi
11618
11619         # check cache is enabled on all obdfilters
11620         if get_osd_param $list '' read_cache_enable | grep 0; then
11621                 skip "oss cache is disabled"
11622         fi
11623
11624         set_osd_param $list '' writethrough_cache_enable 1
11625
11626         # check write cache is enabled on all obdfilters
11627         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
11628                 skip "oss write cache is NOT enabled"
11629         fi
11630
11631         roc_hit_init
11632
11633         #define OBD_FAIL_OBD_NO_LRU  0x609
11634         do_nodes $list $LCTL set_param fail_loc=0x609
11635
11636         # pages should be in the case right after write
11637         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
11638                 error "dd failed"
11639
11640         local BEFORE=$(roc_hit)
11641         cancel_lru_locks osc
11642         cat $DIR/$tfile >/dev/null
11643         local AFTER=$(roc_hit)
11644
11645         do_nodes $list $LCTL set_param fail_loc=0
11646
11647         if ! let "AFTER - BEFORE == CPAGES"; then
11648                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
11649         fi
11650
11651         # the following read invalidates the cache
11652         cancel_lru_locks osc
11653         set_osd_param $list '' read_cache_enable 0
11654         cat $DIR/$tfile >/dev/null
11655
11656         # now data shouldn't be found in the cache
11657         BEFORE=$(roc_hit)
11658         cancel_lru_locks osc
11659         cat $DIR/$tfile >/dev/null
11660         AFTER=$(roc_hit)
11661         if let "AFTER - BEFORE != 0"; then
11662                 error "IN CACHE: before: $BEFORE, after: $AFTER"
11663         fi
11664
11665         set_osd_param $list '' read_cache_enable 1
11666         rm -f $DIR/$tfile
11667 }
11668 run_test 151 "test cache on oss and controls ==============================="
11669
11670 test_152() {
11671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11672
11673         local TF="$TMP/$tfile"
11674
11675         # simulate ENOMEM during write
11676 #define OBD_FAIL_OST_NOMEM      0x226
11677         lctl set_param fail_loc=0x80000226
11678         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
11679         cp $TF $DIR/$tfile
11680         sync || error "sync failed"
11681         lctl set_param fail_loc=0
11682
11683         # discard client's cache
11684         cancel_lru_locks osc
11685
11686         # simulate ENOMEM during read
11687         lctl set_param fail_loc=0x80000226
11688         cmp $TF $DIR/$tfile || error "cmp failed"
11689         lctl set_param fail_loc=0
11690
11691         rm -f $TF
11692 }
11693 run_test 152 "test read/write with enomem ============================"
11694
11695 test_153() {
11696         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
11697 }
11698 run_test 153 "test if fdatasync does not crash ======================="
11699
11700 dot_lustre_fid_permission_check() {
11701         local fid=$1
11702         local ffid=$MOUNT/.lustre/fid/$fid
11703         local test_dir=$2
11704
11705         echo "stat fid $fid"
11706         stat $ffid > /dev/null || error "stat $ffid failed."
11707         echo "touch fid $fid"
11708         touch $ffid || error "touch $ffid failed."
11709         echo "write to fid $fid"
11710         cat /etc/hosts > $ffid || error "write $ffid failed."
11711         echo "read fid $fid"
11712         diff /etc/hosts $ffid || error "read $ffid failed."
11713         echo "append write to fid $fid"
11714         cat /etc/hosts >> $ffid || error "append write $ffid failed."
11715         echo "rename fid $fid"
11716         mv $ffid $test_dir/$tfile.1 &&
11717                 error "rename $ffid to $tfile.1 should fail."
11718         touch $test_dir/$tfile.1
11719         mv $test_dir/$tfile.1 $ffid &&
11720                 error "rename $tfile.1 to $ffid should fail."
11721         rm -f $test_dir/$tfile.1
11722         echo "truncate fid $fid"
11723         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
11724         echo "link fid $fid"
11725         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
11726         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
11727                 echo "setfacl fid $fid"
11728                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
11729                 echo "getfacl fid $fid"
11730                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
11731         fi
11732         echo "unlink fid $fid"
11733         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
11734         echo "mknod fid $fid"
11735         mknod $ffid c 1 3 && error "mknod $ffid should fail."
11736
11737         fid=[0xf00000400:0x1:0x0]
11738         ffid=$MOUNT/.lustre/fid/$fid
11739
11740         echo "stat non-exist fid $fid"
11741         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
11742         echo "write to non-exist fid $fid"
11743         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
11744         echo "link new fid $fid"
11745         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
11746
11747         mkdir -p $test_dir/$tdir
11748         touch $test_dir/$tdir/$tfile
11749         fid=$($LFS path2fid $test_dir/$tdir)
11750         rc=$?
11751         [ $rc -ne 0 ] &&
11752                 error "error: could not get fid for $test_dir/$dir/$tfile."
11753
11754         ffid=$MOUNT/.lustre/fid/$fid
11755
11756         echo "ls $fid"
11757         ls $ffid > /dev/null || error "ls $ffid failed."
11758         echo "touch $fid/$tfile.1"
11759         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
11760
11761         echo "touch $MOUNT/.lustre/fid/$tfile"
11762         touch $MOUNT/.lustre/fid/$tfile && \
11763                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
11764
11765         echo "setxattr to $MOUNT/.lustre/fid"
11766         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
11767
11768         echo "listxattr for $MOUNT/.lustre/fid"
11769         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
11770
11771         echo "delxattr from $MOUNT/.lustre/fid"
11772         setfattr -x trusted.name1 $MOUNT/.lustre/fid
11773
11774         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
11775         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
11776                 error "touch invalid fid should fail."
11777
11778         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
11779         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
11780                 error "touch non-normal fid should fail."
11781
11782         echo "rename $tdir to $MOUNT/.lustre/fid"
11783         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
11784                 error "rename to $MOUNT/.lustre/fid should fail."
11785
11786         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
11787         then            # LU-3547
11788                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
11789                 local new_obf_mode=777
11790
11791                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
11792                 chmod $new_obf_mode $DIR/.lustre/fid ||
11793                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
11794
11795                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
11796                 [ $obf_mode -eq $new_obf_mode ] ||
11797                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
11798
11799                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
11800                 chmod $old_obf_mode $DIR/.lustre/fid ||
11801                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
11802         fi
11803
11804         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
11805         fid=$($LFS path2fid $test_dir/$tfile-2)
11806
11807         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
11808         then # LU-5424
11809                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
11810                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
11811                         error "create lov data thru .lustre failed"
11812         fi
11813         echo "cp /etc/passwd $test_dir/$tfile-2"
11814         cp /etc/passwd $test_dir/$tfile-2 ||
11815                 error "copy to $test_dir/$tfile-2 failed."
11816         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
11817         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
11818                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
11819
11820         rm -rf $test_dir/tfile.lnk
11821         rm -rf $test_dir/$tfile-2
11822 }
11823
11824 test_154A() {
11825         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11826                 skip "Need MDS version at least 2.4.1"
11827
11828         local tf=$DIR/$tfile
11829         touch $tf
11830
11831         local fid=$($LFS path2fid $tf)
11832         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
11833
11834         # check that we get the same pathname back
11835         local found=$($LFS fid2path $MOUNT "$fid")
11836         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
11837         [ "$found" == "$tf" ] ||
11838                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
11839 }
11840 run_test 154A "lfs path2fid and fid2path basic checks"
11841
11842 test_154B() {
11843         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11844                 skip "Need MDS version at least 2.4.1"
11845
11846         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
11847         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
11848         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
11849         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
11850
11851         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
11852         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
11853
11854         # check that we get the same pathname
11855         echo "PFID: $PFID, name: $name"
11856         local FOUND=$($LFS fid2path $MOUNT "$PFID")
11857         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
11858         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
11859                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
11860
11861         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
11862 }
11863 run_test 154B "verify the ll_decode_linkea tool"
11864
11865 test_154a() {
11866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11867         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11868         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
11869                 skip "Need MDS version at least 2.2.51"
11870         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11871
11872         cp /etc/hosts $DIR/$tfile
11873
11874         fid=$($LFS path2fid $DIR/$tfile)
11875         rc=$?
11876         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
11877
11878         dot_lustre_fid_permission_check "$fid" $DIR ||
11879                 error "dot lustre permission check $fid failed"
11880
11881         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
11882
11883         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
11884
11885         touch $MOUNT/.lustre/file &&
11886                 error "creation is not allowed under .lustre"
11887
11888         mkdir $MOUNT/.lustre/dir &&
11889                 error "mkdir is not allowed under .lustre"
11890
11891         rm -rf $DIR/$tfile
11892 }
11893 run_test 154a "Open-by-FID"
11894
11895 test_154b() {
11896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11897         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11898         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
11899         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
11900                 skip "Need MDS version at least 2.2.51"
11901
11902         local remote_dir=$DIR/$tdir/remote_dir
11903         local MDTIDX=1
11904         local rc=0
11905
11906         mkdir -p $DIR/$tdir
11907         $LFS mkdir -i $MDTIDX $remote_dir ||
11908                 error "create remote directory failed"
11909
11910         cp /etc/hosts $remote_dir/$tfile
11911
11912         fid=$($LFS path2fid $remote_dir/$tfile)
11913         rc=$?
11914         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
11915
11916         dot_lustre_fid_permission_check "$fid" $remote_dir ||
11917                 error "dot lustre permission check $fid failed"
11918         rm -rf $DIR/$tdir
11919 }
11920 run_test 154b "Open-by-FID for remote directory"
11921
11922 test_154c() {
11923         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11924                 skip "Need MDS version at least 2.4.1"
11925
11926         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
11927         local FID1=$($LFS path2fid $DIR/$tfile.1)
11928         local FID2=$($LFS path2fid $DIR/$tfile.2)
11929         local FID3=$($LFS path2fid $DIR/$tfile.3)
11930
11931         local N=1
11932         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
11933                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
11934                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
11935                 local want=FID$N
11936                 [ "$FID" = "${!want}" ] ||
11937                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
11938                 N=$((N + 1))
11939         done
11940
11941         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
11942         do
11943                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
11944                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
11945                 N=$((N + 1))
11946         done
11947 }
11948 run_test 154c "lfs path2fid and fid2path multiple arguments"
11949
11950 test_154d() {
11951         remote_mds_nodsh && skip "remote MDS with nodsh"
11952         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
11953                 skip "Need MDS version at least 2.5.53"
11954
11955         if remote_mds; then
11956                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
11957         else
11958                 nid="0@lo"
11959         fi
11960         local proc_ofile="mdt.*.exports.'$nid'.open_files"
11961         local fd
11962         local cmd
11963
11964         rm -f $DIR/$tfile
11965         touch $DIR/$tfile
11966
11967         local fid=$($LFS path2fid $DIR/$tfile)
11968         # Open the file
11969         fd=$(free_fd)
11970         cmd="exec $fd<$DIR/$tfile"
11971         eval $cmd
11972         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
11973         echo "$fid_list" | grep "$fid"
11974         rc=$?
11975
11976         cmd="exec $fd>/dev/null"
11977         eval $cmd
11978         if [ $rc -ne 0 ]; then
11979                 error "FID $fid not found in open files list $fid_list"
11980         fi
11981 }
11982 run_test 154d "Verify open file fid"
11983
11984 test_154e()
11985 {
11986         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
11987                 skip "Need MDS version at least 2.6.50"
11988
11989         if ls -a $MOUNT | grep -q '^\.lustre$'; then
11990                 error ".lustre returned by readdir"
11991         fi
11992 }
11993 run_test 154e ".lustre is not returned by readdir"
11994
11995 test_154f() {
11996         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11997
11998         # create parent directory on a single MDT to avoid cross-MDT hardlinks
11999         test_mkdir -p -c1 $DIR/$tdir/d
12000         # test dirs inherit from its stripe
12001         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
12002         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
12003         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
12004         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
12005         touch $DIR/f
12006
12007         # get fid of parents
12008         local FID0=$($LFS path2fid $DIR/$tdir/d)
12009         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
12010         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
12011         local FID3=$($LFS path2fid $DIR)
12012
12013         # check that path2fid --parents returns expected <parent_fid>/name
12014         # 1) test for a directory (single parent)
12015         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
12016         [ "$parent" == "$FID0/foo1" ] ||
12017                 error "expected parent: $FID0/foo1, got: $parent"
12018
12019         # 2) test for a file with nlink > 1 (multiple parents)
12020         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
12021         echo "$parent" | grep -F "$FID1/$tfile" ||
12022                 error "$FID1/$tfile not returned in parent list"
12023         echo "$parent" | grep -F "$FID2/link" ||
12024                 error "$FID2/link not returned in parent list"
12025
12026         # 3) get parent by fid
12027         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
12028         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12029         echo "$parent" | grep -F "$FID1/$tfile" ||
12030                 error "$FID1/$tfile not returned in parent list (by fid)"
12031         echo "$parent" | grep -F "$FID2/link" ||
12032                 error "$FID2/link not returned in parent list (by fid)"
12033
12034         # 4) test for entry in root directory
12035         parent=$($LFS path2fid --parents $DIR/f)
12036         echo "$parent" | grep -F "$FID3/f" ||
12037                 error "$FID3/f not returned in parent list"
12038
12039         # 5) test it on root directory
12040         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
12041                 error "$MOUNT should not have parents"
12042
12043         # enable xattr caching and check that linkea is correctly updated
12044         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12045         save_lustre_params client "llite.*.xattr_cache" > $save
12046         lctl set_param llite.*.xattr_cache 1
12047
12048         # 6.1) linkea update on rename
12049         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
12050
12051         # get parents by fid
12052         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12053         # foo1 should no longer be returned in parent list
12054         echo "$parent" | grep -F "$FID1" &&
12055                 error "$FID1 should no longer be in parent list"
12056         # the new path should appear
12057         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
12058                 error "$FID2/$tfile.moved is not in parent list"
12059
12060         # 6.2) linkea update on unlink
12061         rm -f $DIR/$tdir/d/foo2/link
12062         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12063         # foo2/link should no longer be returned in parent list
12064         echo "$parent" | grep -F "$FID2/link" &&
12065                 error "$FID2/link should no longer be in parent list"
12066         true
12067
12068         rm -f $DIR/f
12069         restore_lustre_params < $save
12070         rm -f $save
12071 }
12072 run_test 154f "get parent fids by reading link ea"
12073
12074 test_154g()
12075 {
12076         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12077         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
12078            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
12079                 skip "Need MDS version at least 2.6.92"
12080
12081         mkdir -p $DIR/$tdir
12082         llapi_fid_test -d $DIR/$tdir
12083 }
12084 run_test 154g "various llapi FID tests"
12085
12086 test_155_small_load() {
12087     local temp=$TMP/$tfile
12088     local file=$DIR/$tfile
12089
12090     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
12091         error "dd of=$temp bs=6096 count=1 failed"
12092     cp $temp $file
12093     cancel_lru_locks $OSC
12094     cmp $temp $file || error "$temp $file differ"
12095
12096     $TRUNCATE $temp 6000
12097     $TRUNCATE $file 6000
12098     cmp $temp $file || error "$temp $file differ (truncate1)"
12099
12100     echo "12345" >>$temp
12101     echo "12345" >>$file
12102     cmp $temp $file || error "$temp $file differ (append1)"
12103
12104     echo "12345" >>$temp
12105     echo "12345" >>$file
12106     cmp $temp $file || error "$temp $file differ (append2)"
12107
12108     rm -f $temp $file
12109     true
12110 }
12111
12112 test_155_big_load() {
12113         remote_ost_nodsh && skip "remote OST with nodsh"
12114
12115         local temp=$TMP/$tfile
12116         local file=$DIR/$tfile
12117
12118         free_min_max
12119         local cache_size=$(do_facet ost$((MAXI+1)) \
12120                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
12121         local large_file_size=$((cache_size * 2))
12122
12123         echo "OSS cache size: $cache_size KB"
12124         echo "Large file size: $large_file_size KB"
12125
12126         [ $MAXV -le $large_file_size ] &&
12127                 skip_env "max available OST size needs > $large_file_size KB"
12128
12129         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
12130
12131         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
12132                 error "dd of=$temp bs=$large_file_size count=1k failed"
12133         cp $temp $file
12134         ls -lh $temp $file
12135         cancel_lru_locks osc
12136         cmp $temp $file || error "$temp $file differ"
12137
12138         rm -f $temp $file
12139         true
12140 }
12141
12142 save_writethrough() {
12143         local facets=$(get_facets OST)
12144
12145         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
12146 }
12147
12148 test_155a() {
12149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12150
12151         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12152
12153         save_writethrough $p
12154
12155         set_cache read on
12156         set_cache writethrough on
12157         test_155_small_load
12158         restore_lustre_params < $p
12159         rm -f $p
12160 }
12161 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
12162
12163 test_155b() {
12164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12165
12166         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12167
12168         save_writethrough $p
12169
12170         set_cache read on
12171         set_cache writethrough off
12172         test_155_small_load
12173         restore_lustre_params < $p
12174         rm -f $p
12175 }
12176 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
12177
12178 test_155c() {
12179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12180
12181         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12182
12183         save_writethrough $p
12184
12185         set_cache read off
12186         set_cache writethrough on
12187         test_155_small_load
12188         restore_lustre_params < $p
12189         rm -f $p
12190 }
12191 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
12192
12193 test_155d() {
12194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12195
12196         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12197
12198         save_writethrough $p
12199
12200         set_cache read off
12201         set_cache writethrough off
12202         test_155_small_load
12203         restore_lustre_params < $p
12204         rm -f $p
12205 }
12206 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
12207
12208 test_155e() {
12209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12210
12211         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12212
12213         save_writethrough $p
12214
12215         set_cache read on
12216         set_cache writethrough on
12217         test_155_big_load
12218         restore_lustre_params < $p
12219         rm -f $p
12220 }
12221 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
12222
12223 test_155f() {
12224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12225
12226         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12227
12228         save_writethrough $p
12229
12230         set_cache read on
12231         set_cache writethrough off
12232         test_155_big_load
12233         restore_lustre_params < $p
12234         rm -f $p
12235 }
12236 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
12237
12238 test_155g() {
12239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12240
12241         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12242
12243         save_writethrough $p
12244
12245         set_cache read off
12246         set_cache writethrough on
12247         test_155_big_load
12248         restore_lustre_params < $p
12249         rm -f $p
12250 }
12251 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
12252
12253 test_155h() {
12254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12255
12256         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12257
12258         save_writethrough $p
12259
12260         set_cache read off
12261         set_cache writethrough off
12262         test_155_big_load
12263         restore_lustre_params < $p
12264         rm -f $p
12265 }
12266 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
12267
12268 test_156() {
12269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12270         remote_ost_nodsh && skip "remote OST with nodsh"
12271         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
12272                 skip "stats not implemented on old servers"
12273         [ "$ost1_FSTYPE" = "zfs" ] &&
12274                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
12275
12276         local CPAGES=3
12277         local BEFORE
12278         local AFTER
12279         local file="$DIR/$tfile"
12280         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12281
12282         save_writethrough $p
12283         roc_hit_init
12284
12285         log "Turn on read and write cache"
12286         set_cache read on
12287         set_cache writethrough on
12288
12289         log "Write data and read it back."
12290         log "Read should be satisfied from the cache."
12291         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12292         BEFORE=$(roc_hit)
12293         cancel_lru_locks osc
12294         cat $file >/dev/null
12295         AFTER=$(roc_hit)
12296         if ! let "AFTER - BEFORE == CPAGES"; then
12297                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12298         else
12299                 log "cache hits:: before: $BEFORE, after: $AFTER"
12300         fi
12301
12302         log "Read again; it should be satisfied from the cache."
12303         BEFORE=$AFTER
12304         cancel_lru_locks osc
12305         cat $file >/dev/null
12306         AFTER=$(roc_hit)
12307         if ! let "AFTER - BEFORE == CPAGES"; then
12308                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12309         else
12310                 log "cache hits:: before: $BEFORE, after: $AFTER"
12311         fi
12312
12313         log "Turn off the read cache and turn on the write cache"
12314         set_cache read off
12315         set_cache writethrough on
12316
12317         log "Read again; it should be satisfied from the cache."
12318         BEFORE=$(roc_hit)
12319         cancel_lru_locks osc
12320         cat $file >/dev/null
12321         AFTER=$(roc_hit)
12322         if ! let "AFTER - BEFORE == CPAGES"; then
12323                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12324         else
12325                 log "cache hits:: before: $BEFORE, after: $AFTER"
12326         fi
12327
12328         log "Read again; it should not be satisfied from the cache."
12329         BEFORE=$AFTER
12330         cancel_lru_locks osc
12331         cat $file >/dev/null
12332         AFTER=$(roc_hit)
12333         if ! let "AFTER - BEFORE == 0"; then
12334                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12335         else
12336                 log "cache hits:: before: $BEFORE, after: $AFTER"
12337         fi
12338
12339         log "Write data and read it back."
12340         log "Read should be satisfied from the cache."
12341         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12342         BEFORE=$(roc_hit)
12343         cancel_lru_locks osc
12344         cat $file >/dev/null
12345         AFTER=$(roc_hit)
12346         if ! let "AFTER - BEFORE == CPAGES"; then
12347                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12348         else
12349                 log "cache hits:: before: $BEFORE, after: $AFTER"
12350         fi
12351
12352         log "Read again; it should not be satisfied from the cache."
12353         BEFORE=$AFTER
12354         cancel_lru_locks osc
12355         cat $file >/dev/null
12356         AFTER=$(roc_hit)
12357         if ! let "AFTER - BEFORE == 0"; then
12358                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12359         else
12360                 log "cache hits:: before: $BEFORE, after: $AFTER"
12361         fi
12362
12363         log "Turn off read and write cache"
12364         set_cache read off
12365         set_cache writethrough off
12366
12367         log "Write data and read it back"
12368         log "It should not be satisfied from the cache."
12369         rm -f $file
12370         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12371         cancel_lru_locks osc
12372         BEFORE=$(roc_hit)
12373         cat $file >/dev/null
12374         AFTER=$(roc_hit)
12375         if ! let "AFTER - BEFORE == 0"; then
12376                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12377         else
12378                 log "cache hits:: before: $BEFORE, after: $AFTER"
12379         fi
12380
12381         log "Turn on the read cache and turn off the write cache"
12382         set_cache read on
12383         set_cache writethrough off
12384
12385         log "Write data and read it back"
12386         log "It should not be satisfied from the cache."
12387         rm -f $file
12388         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12389         BEFORE=$(roc_hit)
12390         cancel_lru_locks osc
12391         cat $file >/dev/null
12392         AFTER=$(roc_hit)
12393         if ! let "AFTER - BEFORE == 0"; then
12394                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12395         else
12396                 log "cache hits:: before: $BEFORE, after: $AFTER"
12397         fi
12398
12399         log "Read again; it should be satisfied from the cache."
12400         BEFORE=$(roc_hit)
12401         cancel_lru_locks osc
12402         cat $file >/dev/null
12403         AFTER=$(roc_hit)
12404         if ! let "AFTER - BEFORE == CPAGES"; then
12405                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12406         else
12407                 log "cache hits:: before: $BEFORE, after: $AFTER"
12408         fi
12409
12410         restore_lustre_params < $p
12411         rm -f $p $file
12412 }
12413 run_test 156 "Verification of tunables"
12414
12415 test_160a() {
12416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12417         remote_mds_nodsh && skip "remote MDS with nodsh"
12418         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12419                 skip "Need MDS version at least 2.2.0"
12420
12421         changelog_register || error "changelog_register failed"
12422         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12423         changelog_users $SINGLEMDS | grep -q $cl_user ||
12424                 error "User $cl_user not found in changelog_users"
12425
12426         # change something
12427         test_mkdir -p $DIR/$tdir/pics/2008/zachy
12428         changelog_clear 0 || error "changelog_clear failed"
12429         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
12430         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
12431         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
12432         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
12433         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
12434         rm $DIR/$tdir/pics/desktop.jpg
12435
12436         changelog_dump | tail -10
12437
12438         echo "verifying changelog mask"
12439         changelog_chmask "-MKDIR"
12440         changelog_chmask "-CLOSE"
12441
12442         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
12443         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
12444
12445         changelog_chmask "+MKDIR"
12446         changelog_chmask "+CLOSE"
12447
12448         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
12449         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
12450
12451         changelog_dump | tail -10
12452         MKDIRS=$(changelog_dump | grep -c "MKDIR")
12453         CLOSES=$(changelog_dump | grep -c "CLOSE")
12454         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
12455         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
12456
12457         # verify contents
12458         echo "verifying target fid"
12459         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
12460         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
12461         [ "$fidc" == "$fidf" ] ||
12462                 error "changelog '$tfile' fid $fidc != file fid $fidf"
12463         echo "verifying parent fid"
12464         # The FID returned from the Changelog may be the directory shard on
12465         # a different MDT, and not the FID returned by path2fid on the parent.
12466         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
12467         # since this is what will matter when recreating this file in the tree.
12468         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
12469         local pathp=$($LFS fid2path $MOUNT "$fidp")
12470         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
12471                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
12472
12473         echo "getting records for $cl_user"
12474         changelog_users $SINGLEMDS
12475         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
12476         local nclr=3
12477         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
12478                 error "changelog_clear failed"
12479         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
12480         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
12481         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
12482                 error "user index expect $user_rec1 + $nclr != $user_rec2"
12483
12484         local min0_rec=$(changelog_users $SINGLEMDS |
12485                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
12486         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
12487                           awk '{ print $1; exit; }')
12488
12489         changelog_dump | tail -n 5
12490         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
12491         [ $first_rec == $((min0_rec + 1)) ] ||
12492                 error "first index should be $min0_rec + 1 not $first_rec"
12493
12494         # LU-3446 changelog index reset on MDT restart
12495         local cur_rec1=$(changelog_users $SINGLEMDS |
12496                          awk '/^current.index:/ { print $NF }')
12497         changelog_clear 0 ||
12498                 error "clear all changelog records for $cl_user failed"
12499         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
12500         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
12501                 error "Fail to start $SINGLEMDS"
12502         local cur_rec2=$(changelog_users $SINGLEMDS |
12503                          awk '/^current.index:/ { print $NF }')
12504         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
12505         [ $cur_rec1 == $cur_rec2 ] ||
12506                 error "current index should be $cur_rec1 not $cur_rec2"
12507
12508         echo "verifying users from this test are deregistered"
12509         changelog_deregister || error "changelog_deregister failed"
12510         changelog_users $SINGLEMDS | grep -q $cl_user &&
12511                 error "User '$cl_user' still in changelog_users"
12512
12513         # lctl get_param -n mdd.*.changelog_users
12514         # current index: 144
12515         # ID    index (idle seconds)
12516         # cl3   144 (2)
12517         if ! changelog_users $SINGLEMDS | grep "^cl"; then
12518                 # this is the normal case where all users were deregistered
12519                 # make sure no new records are added when no users are present
12520                 local last_rec1=$(changelog_users $SINGLEMDS |
12521                                   awk '/^current.index:/ { print $NF }')
12522                 touch $DIR/$tdir/chloe
12523                 local last_rec2=$(changelog_users $SINGLEMDS |
12524                                   awk '/^current.index:/ { print $NF }')
12525                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
12526                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
12527         else
12528                 # any changelog users must be leftovers from a previous test
12529                 changelog_users $SINGLEMDS
12530                 echo "other changelog users; can't verify off"
12531         fi
12532 }
12533 run_test 160a "changelog sanity"
12534
12535 test_160b() { # LU-3587
12536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12537         remote_mds_nodsh && skip "remote MDS with nodsh"
12538         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12539                 skip "Need MDS version at least 2.2.0"
12540
12541         changelog_register || error "changelog_register failed"
12542         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12543         changelog_users $SINGLEMDS | grep -q $cl_user ||
12544                 error "User '$cl_user' not found in changelog_users"
12545
12546         local longname1=$(str_repeat a 255)
12547         local longname2=$(str_repeat b 255)
12548
12549         cd $DIR
12550         echo "creating very long named file"
12551         touch $longname1 || error "create of '$longname1' failed"
12552         echo "renaming very long named file"
12553         mv $longname1 $longname2
12554
12555         changelog_dump | grep RENME | tail -n 5
12556         rm -f $longname2
12557 }
12558 run_test 160b "Verify that very long rename doesn't crash in changelog"
12559
12560 test_160c() {
12561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12562         remote_mds_nodsh && skip "remote MDS with nodsh"
12563
12564         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
12565                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
12566                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
12567                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
12568
12569         local rc=0
12570
12571         # Registration step
12572         changelog_register || error "changelog_register failed"
12573
12574         rm -rf $DIR/$tdir
12575         mkdir -p $DIR/$tdir
12576         $MCREATE $DIR/$tdir/foo_160c
12577         changelog_chmask "-TRUNC"
12578         $TRUNCATE $DIR/$tdir/foo_160c 200
12579         changelog_chmask "+TRUNC"
12580         $TRUNCATE $DIR/$tdir/foo_160c 199
12581         changelog_dump | tail -n 5
12582         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
12583         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
12584 }
12585 run_test 160c "verify that changelog log catch the truncate event"
12586
12587 test_160d() {
12588         remote_mds_nodsh && skip "remote MDS with nodsh"
12589         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
12590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12591         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
12592                 skip "Need MDS version at least 2.7.60"
12593
12594         # Registration step
12595         changelog_register || error "changelog_register failed"
12596
12597         mkdir -p $DIR/$tdir/migrate_dir
12598         changelog_clear 0 || error "changelog_clear failed"
12599
12600         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
12601         changelog_dump | tail -n 5
12602         local migrates=$(changelog_dump | grep -c "MIGRT")
12603         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
12604 }
12605 run_test 160d "verify that changelog log catch the migrate event"
12606
12607 test_160e() {
12608         remote_mds_nodsh && skip "remote MDS with nodsh"
12609
12610         # Create a user
12611         changelog_register || error "changelog_register failed"
12612
12613         # Delete a future user (expect fail)
12614         local MDT0=$(facet_svc $SINGLEMDS)
12615         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
12616         local rc=$?
12617
12618         if [ $rc -eq 0 ]; then
12619                 error "Deleted non-existant user cl77"
12620         elif [ $rc -ne 2 ]; then
12621                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
12622         fi
12623
12624         # Clear to a bad index (1 billion should be safe)
12625         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
12626         rc=$?
12627
12628         if [ $rc -eq 0 ]; then
12629                 error "Successfully cleared to invalid CL index"
12630         elif [ $rc -ne 22 ]; then
12631                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
12632         fi
12633 }
12634 run_test 160e "changelog negative testing (should return errors)"
12635
12636 test_160f() {
12637         remote_mds_nodsh && skip "remote MDS with nodsh" && return
12638         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12639                 skip "Need MDS version at least 2.10.56"
12640
12641         local mdts=$(comma_list $(mdts_nodes))
12642
12643         # Create a user
12644         changelog_register || error "first changelog_register failed"
12645         changelog_register || error "second changelog_register failed"
12646         local cl_users
12647         declare -A cl_user1
12648         declare -A cl_user2
12649         local user_rec1
12650         local user_rec2
12651         local i
12652
12653         # generate some changelog records to accumulate on each MDT
12654         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
12655         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12656                 error "create $DIR/$tdir/$tfile failed"
12657
12658         # check changelogs have been generated
12659         local nbcl=$(changelog_dump | wc -l)
12660         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12661
12662         for param in "changelog_max_idle_time=10" \
12663                      "changelog_gc=1" \
12664                      "changelog_min_gc_interval=2" \
12665                      "changelog_min_free_cat_entries=3"; do
12666                 local MDT0=$(facet_svc $SINGLEMDS)
12667                 local var="${param%=*}"
12668                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12669
12670                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12671                 do_nodes $mdts $LCTL set_param mdd.*.$param
12672         done
12673
12674         # force cl_user2 to be idle (1st part)
12675         sleep 9
12676
12677         # simulate changelog catalog almost full
12678         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
12679         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
12680
12681         for i in $(seq $MDSCOUNT); do
12682                 cl_users=(${CL_USERS[mds$i]})
12683                 cl_user1[mds$i]="${cl_users[0]}"
12684                 cl_user2[mds$i]="${cl_users[1]}"
12685
12686                 [ -n "${cl_user1[mds$i]}" ] ||
12687                         error "mds$i: no user registered"
12688                 [ -n "${cl_user2[mds$i]}" ] ||
12689                         error "mds$i: only ${cl_user2[mds$i]} is registered"
12690
12691                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12692                 [ -n "$user_rec1" ] ||
12693                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12694                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12695                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12696                 [ -n "$user_rec2" ] ||
12697                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12698                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12699                      "$user_rec1 + 2 == $user_rec2"
12700                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12701                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12702                               "$user_rec1 + 2, but is $user_rec2"
12703                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12704                 [ -n "$user_rec2" ] ||
12705                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12706                 [ $user_rec1 == $user_rec2 ] ||
12707                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12708                               "$user_rec1, but is $user_rec2"
12709         done
12710
12711         # force cl_user2 to be idle (2nd part) and to reach
12712         # changelog_max_idle_time
12713         sleep 2
12714
12715         # generate one more changelog to trigger fail_loc
12716         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12717                 error "create $DIR/$tdir/${tfile}bis failed"
12718
12719         # ensure gc thread is done
12720         for i in $(mdts_nodes); do
12721                 wait_update $i \
12722                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
12723                         error "$i: GC-thread not done"
12724         done
12725
12726         local first_rec
12727         for i in $(seq $MDSCOUNT); do
12728                 # check cl_user1 still registered
12729                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
12730                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12731                 # check cl_user2 unregistered
12732                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
12733                         error "mds$i: User ${cl_user2[mds$i]} still registered"
12734
12735                 # check changelogs are present and starting at $user_rec1 + 1
12736                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12737                 [ -n "$user_rec1" ] ||
12738                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12739                 first_rec=$($LFS changelog $(facet_svc mds$i) |
12740                             awk '{ print $1; exit; }')
12741
12742                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
12743                 [ $((user_rec1 + 1)) == $first_rec ] ||
12744                         error "mds$i: first index should be $user_rec1 + 1, " \
12745                               "but is $first_rec"
12746         done
12747 }
12748 run_test 160f "changelog garbage collect (timestamped users)"
12749
12750 test_160g() {
12751         remote_mds_nodsh && skip "remote MDS with nodsh"
12752         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12753                 skip "Need MDS version at least 2.10.56"
12754
12755         local mdts=$(comma_list $(mdts_nodes))
12756
12757         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
12758         do_nodes $mdts $LCTL set_param fail_loc=0x1314
12759
12760         # Create a user
12761         changelog_register || error "first changelog_register failed"
12762         changelog_register || error "second changelog_register failed"
12763         local cl_users
12764         declare -A cl_user1
12765         declare -A cl_user2
12766         local user_rec1
12767         local user_rec2
12768         local i
12769
12770         # generate some changelog records to accumulate on each MDT
12771         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
12772         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12773                 error "create $DIR/$tdir/$tfile failed"
12774
12775         # check changelogs have been generated
12776         local nbcl=$(changelog_dump | wc -l)
12777         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12778
12779         # reduce the max_idle_indexes value to make sure we exceed it
12780         max_ndx=$((nbcl / 2 - 1))
12781
12782         for param in "changelog_max_idle_indexes=$max_ndx" \
12783                      "changelog_gc=1" \
12784                      "changelog_min_gc_interval=2" \
12785                      "changelog_min_free_cat_entries=3"; do
12786                 local MDT0=$(facet_svc $SINGLEMDS)
12787                 local var="${param%=*}"
12788                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12789
12790                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12791                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
12792                         error "unable to set mdd.*.$param"
12793         done
12794
12795         # simulate changelog catalog almost full
12796         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
12797         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
12798
12799         for i in $(seq $MDSCOUNT); do
12800                 cl_users=(${CL_USERS[mds$i]})
12801                 cl_user1[mds$i]="${cl_users[0]}"
12802                 cl_user2[mds$i]="${cl_users[1]}"
12803
12804                 [ -n "${cl_user1[mds$i]}" ] ||
12805                         error "mds$i: no user registered"
12806                 [ -n "${cl_user2[mds$i]}" ] ||
12807                         error "mds$i: only ${cl_user1[mds$i]} is registered"
12808
12809                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12810                 [ -n "$user_rec1" ] ||
12811                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12812                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12813                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12814                 [ -n "$user_rec2" ] ||
12815                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12816                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12817                      "$user_rec1 + 2 == $user_rec2"
12818                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12819                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12820                               "$user_rec1 + 2, but is $user_rec2"
12821                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12822                 [ -n "$user_rec2" ] ||
12823                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12824                 [ $user_rec1 == $user_rec2 ] ||
12825                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12826                               "$user_rec1, but is $user_rec2"
12827         done
12828
12829         # ensure we are past the previous changelog_min_gc_interval set above
12830         sleep 2
12831
12832         # generate one more changelog to trigger fail_loc
12833         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12834                 error "create $DIR/$tdir/${tfile}bis failed"
12835
12836         # ensure gc thread is done
12837         for i in $(mdts_nodes); do
12838                 wait_update $i \
12839                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
12840                         error "$i: GC-thread not done"
12841         done
12842
12843         local first_rec
12844         for i in $(seq $MDSCOUNT); do
12845                 # check cl_user1 still registered
12846                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
12847                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12848                 # check cl_user2 unregistered
12849                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
12850                         error "mds$i: User ${cl_user2[mds$i]} still registered"
12851
12852                 # check changelogs are present and starting at $user_rec1 + 1
12853                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12854                 [ -n "$user_rec1" ] ||
12855                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12856                 first_rec=$($LFS changelog $(facet_svc mds$i) |
12857                             awk '{ print $1; exit; }')
12858
12859                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
12860                 [ $((user_rec1 + 1)) == $first_rec ] ||
12861                         error "mds$i: first index should be $user_rec1 + 1, " \
12862                               "but is $first_rec"
12863         done
12864 }
12865 run_test 160g "changelog garbage collect (old users)"
12866
12867 test_160h() {
12868         remote_mds_nodsh && skip "remote MDS with nodsh" && return
12869         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12870                 skip "Need MDS version at least 2.10.56"
12871
12872         local mdts=$(comma_list $(mdts_nodes))
12873
12874         # Create a user
12875         changelog_register || error "first changelog_register failed"
12876         changelog_register || error "second changelog_register failed"
12877         local cl_users
12878         declare -A cl_user1
12879         declare -A cl_user2
12880         local user_rec1
12881         local user_rec2
12882         local i
12883
12884         # generate some changelog records to accumulate on each MDT
12885         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
12886         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12887                 error "create $DIR/$tdir/$tfile failed"
12888
12889         # check changelogs have been generated
12890         local nbcl=$(changelog_dump | wc -l)
12891         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12892
12893         for param in "changelog_max_idle_time=10" \
12894                      "changelog_gc=1" \
12895                      "changelog_min_gc_interval=2"; do
12896                 local MDT0=$(facet_svc $SINGLEMDS)
12897                 local var="${param%=*}"
12898                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12899
12900                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12901                 do_nodes $mdts $LCTL set_param mdd.*.$param
12902         done
12903
12904         # force cl_user2 to be idle (1st part)
12905         sleep 9
12906
12907         for i in $(seq $MDSCOUNT); do
12908                 cl_users=(${CL_USERS[mds$i]})
12909                 cl_user1[mds$i]="${cl_users[0]}"
12910                 cl_user2[mds$i]="${cl_users[1]}"
12911
12912                 [ -n "${cl_user1[mds$i]}" ] ||
12913                         error "mds$i: no user registered"
12914                 [ -n "${cl_user2[mds$i]}" ] ||
12915                         error "mds$i: only ${cl_user2[mds$i]} is registered"
12916
12917                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12918                 [ -n "$user_rec1" ] ||
12919                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12920                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12921                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12922                 [ -n "$user_rec2" ] ||
12923                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12924                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12925                      "$user_rec1 + 2 == $user_rec2"
12926                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12927                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12928                               "$user_rec1 + 2, but is $user_rec2"
12929                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12930                 [ -n "$user_rec2" ] ||
12931                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12932                 [ $user_rec1 == $user_rec2 ] ||
12933                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12934                               "$user_rec1, but is $user_rec2"
12935         done
12936
12937         # force cl_user2 to be idle (2nd part) and to reach
12938         # changelog_max_idle_time
12939         sleep 2
12940
12941         # force each GC-thread start and block then
12942         # one per MDT/MDD, set fail_val accordingly
12943         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
12944         do_nodes $mdts $LCTL set_param fail_loc=0x1316
12945
12946         # generate more changelogs to trigger fail_loc
12947         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12948                 error "create $DIR/$tdir/${tfile}bis failed"
12949
12950         # stop MDT to stop GC-thread, should be done in back-ground as it will
12951         # block waiting for the thread to be released and exit
12952         declare -A stop_pids
12953         for i in $(seq $MDSCOUNT); do
12954                 stop mds$i &
12955                 stop_pids[mds$i]=$!
12956         done
12957
12958         for i in $(mdts_nodes); do
12959                 local facet
12960                 local nb=0
12961                 local facets=$(facets_up_on_host $i)
12962
12963                 for facet in ${facets//,/ }; do
12964                         if [[ $facet == mds* ]]; then
12965                                 nb=$((nb + 1))
12966                         fi
12967                 done
12968                 # ensure each MDS's gc threads are still present and all in "R"
12969                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
12970                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
12971                         error "$i: expected $nb GC-thread"
12972                 wait_update $i \
12973                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
12974                         "R" 20 ||
12975                         error "$i: GC-thread not found in R-state"
12976                 # check umounts of each MDT on MDS have reached kthread_stop()
12977                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
12978                         error "$i: expected $nb umount"
12979                 wait_update $i \
12980                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
12981                         error "$i: umount not found in D-state"
12982         done
12983
12984         # release all GC-threads
12985         do_nodes $mdts $LCTL set_param fail_loc=0
12986
12987         # wait for MDT stop to complete
12988         for i in $(seq $MDSCOUNT); do
12989                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
12990         done
12991
12992         # XXX
12993         # may try to check if any orphan changelog records are present
12994         # via ldiskfs/zfs and llog_reader...
12995
12996         # re-start/mount MDTs
12997         for i in $(seq $MDSCOUNT); do
12998                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
12999                         error "Fail to start mds$i"
13000         done
13001
13002         local first_rec
13003         for i in $(seq $MDSCOUNT); do
13004                 # check cl_user1 still registered
13005                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13006                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13007                 # check cl_user2 unregistered
13008                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13009                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13010
13011                 # check changelogs are present and starting at $user_rec1 + 1
13012                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13013                 [ -n "$user_rec1" ] ||
13014                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13015                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13016                             awk '{ print $1; exit; }')
13017
13018                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13019                 [ $((user_rec1 + 1)) == $first_rec ] ||
13020                         error "mds$i: first index should be $user_rec1 + 1, " \
13021                               "but is $first_rec"
13022         done
13023 }
13024 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
13025               "during mount"
13026
13027 test_160i() {
13028
13029         local mdts=$(comma_list $(mdts_nodes))
13030
13031         changelog_register || error "first changelog_register failed"
13032
13033         # generate some changelog records to accumulate on each MDT
13034         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13035         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13036                 error "create $DIR/$tdir/$tfile failed"
13037
13038         # check changelogs have been generated
13039         local nbcl=$(changelog_dump | wc -l)
13040         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13041
13042         # simulate race between register and unregister
13043         # XXX as fail_loc is set per-MDS, with DNE configs the race
13044         # simulation will only occur for one MDT per MDS and for the
13045         # others the normal race scenario will take place
13046         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
13047         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
13048         do_nodes $mdts $LCTL set_param fail_val=1
13049
13050         # unregister 1st user
13051         changelog_deregister &
13052         local pid1=$!
13053         # wait some time for deregister work to reach race rdv
13054         sleep 2
13055         # register 2nd user
13056         changelog_register || error "2nd user register failed"
13057
13058         wait $pid1 || error "1st user deregister failed"
13059
13060         local i
13061         local last_rec
13062         declare -A LAST_REC
13063         for i in $(seq $MDSCOUNT); do
13064                 if changelog_users mds$i | grep "^cl"; then
13065                         # make sure new records are added with one user present
13066                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
13067                                           awk '/^current.index:/ { print $NF }')
13068                 else
13069                         error "mds$i has no user registered"
13070                 fi
13071         done
13072
13073         # generate more changelog records to accumulate on each MDT
13074         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13075                 error "create $DIR/$tdir/${tfile}bis failed"
13076
13077         for i in $(seq $MDSCOUNT); do
13078                 last_rec=$(changelog_users $SINGLEMDS |
13079                            awk '/^current.index:/ { print $NF }')
13080                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
13081                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
13082                         error "changelogs are off on mds$i"
13083         done
13084 }
13085 run_test 160i "changelog user register/unregister race"
13086
13087 test_161a() {
13088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13089
13090         test_mkdir -c1 $DIR/$tdir
13091         cp /etc/hosts $DIR/$tdir/$tfile
13092         test_mkdir -c1 $DIR/$tdir/foo1
13093         test_mkdir -c1 $DIR/$tdir/foo2
13094         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
13095         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
13096         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
13097         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
13098         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
13099         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13100                 $LFS fid2path $DIR $FID
13101                 error "bad link ea"
13102         fi
13103         # middle
13104         rm $DIR/$tdir/foo2/zachary
13105         # last
13106         rm $DIR/$tdir/foo2/thor
13107         # first
13108         rm $DIR/$tdir/$tfile
13109         # rename
13110         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
13111         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
13112                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
13113         rm $DIR/$tdir/foo2/maggie
13114
13115         # overflow the EA
13116         local longname=$tfile.avg_len_is_thirty_two_
13117         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
13118                 error_noexit 'failed to unlink many hardlinks'" EXIT
13119         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
13120                 error "failed to hardlink many files"
13121         links=$($LFS fid2path $DIR $FID | wc -l)
13122         echo -n "${links}/1000 links in link EA"
13123         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
13124 }
13125 run_test 161a "link ea sanity"
13126
13127 test_161b() {
13128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13129         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
13130
13131         local MDTIDX=1
13132         local remote_dir=$DIR/$tdir/remote_dir
13133
13134         mkdir -p $DIR/$tdir
13135         $LFS mkdir -i $MDTIDX $remote_dir ||
13136                 error "create remote directory failed"
13137
13138         cp /etc/hosts $remote_dir/$tfile
13139         mkdir -p $remote_dir/foo1
13140         mkdir -p $remote_dir/foo2
13141         ln $remote_dir/$tfile $remote_dir/foo1/sofia
13142         ln $remote_dir/$tfile $remote_dir/foo2/zachary
13143         ln $remote_dir/$tfile $remote_dir/foo1/luna
13144         ln $remote_dir/$tfile $remote_dir/foo2/thor
13145
13146         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
13147                      tr -d ']')
13148         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13149                 $LFS fid2path $DIR $FID
13150                 error "bad link ea"
13151         fi
13152         # middle
13153         rm $remote_dir/foo2/zachary
13154         # last
13155         rm $remote_dir/foo2/thor
13156         # first
13157         rm $remote_dir/$tfile
13158         # rename
13159         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
13160         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
13161         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
13162                 $LFS fid2path $DIR $FID
13163                 error "bad link rename"
13164         fi
13165         rm $remote_dir/foo2/maggie
13166
13167         # overflow the EA
13168         local longname=filename_avg_len_is_thirty_two_
13169         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
13170                 error "failed to hardlink many files"
13171         links=$($LFS fid2path $DIR $FID | wc -l)
13172         echo -n "${links}/1000 links in link EA"
13173         [[ ${links} -gt 60 ]] ||
13174                 error "expected at least 60 links in link EA"
13175         unlinkmany $remote_dir/foo2/$longname 1000 ||
13176         error "failed to unlink many hardlinks"
13177 }
13178 run_test 161b "link ea sanity under remote directory"
13179
13180 test_161c() {
13181         remote_mds_nodsh && skip "remote MDS with nodsh"
13182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13183         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
13184                 skip "Need MDS version at least 2.1.5"
13185
13186         # define CLF_RENAME_LAST 0x0001
13187         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
13188         changelog_register || error "changelog_register failed"
13189
13190         rm -rf $DIR/$tdir
13191         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
13192         touch $DIR/$tdir/foo_161c
13193         touch $DIR/$tdir/bar_161c
13194         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13195         changelog_dump | grep RENME | tail -n 5
13196         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13197         changelog_clear 0 || error "changelog_clear failed"
13198         if [ x$flags != "x0x1" ]; then
13199                 error "flag $flags is not 0x1"
13200         fi
13201
13202         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
13203         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
13204         touch $DIR/$tdir/foo_161c
13205         touch $DIR/$tdir/bar_161c
13206         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13207         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13208         changelog_dump | grep RENME | tail -n 5
13209         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13210         changelog_clear 0 || error "changelog_clear failed"
13211         if [ x$flags != "x0x0" ]; then
13212                 error "flag $flags is not 0x0"
13213         fi
13214         echo "rename overwrite a target having nlink > 1," \
13215                 "changelog record has flags of $flags"
13216
13217         # rename doesn't overwrite a target (changelog flag 0x0)
13218         touch $DIR/$tdir/foo_161c
13219         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
13220         changelog_dump | grep RENME | tail -n 5
13221         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
13222         changelog_clear 0 || error "changelog_clear failed"
13223         if [ x$flags != "x0x0" ]; then
13224                 error "flag $flags is not 0x0"
13225         fi
13226         echo "rename doesn't overwrite a target," \
13227                 "changelog record has flags of $flags"
13228
13229         # define CLF_UNLINK_LAST 0x0001
13230         # unlink a file having nlink = 1 (changelog flag 0x1)
13231         rm -f $DIR/$tdir/foo2_161c
13232         changelog_dump | grep UNLNK | tail -n 5
13233         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13234         changelog_clear 0 || error "changelog_clear failed"
13235         if [ x$flags != "x0x1" ]; then
13236                 error "flag $flags is not 0x1"
13237         fi
13238         echo "unlink a file having nlink = 1," \
13239                 "changelog record has flags of $flags"
13240
13241         # unlink a file having nlink > 1 (changelog flag 0x0)
13242         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13243         rm -f $DIR/$tdir/foobar_161c
13244         changelog_dump | grep UNLNK | tail -n 5
13245         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13246         changelog_clear 0 || error "changelog_clear failed"
13247         if [ x$flags != "x0x0" ]; then
13248                 error "flag $flags is not 0x0"
13249         fi
13250         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
13251 }
13252 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
13253
13254 test_161d() {
13255         remote_mds_nodsh && skip "remote MDS with nodsh"
13256         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
13257
13258         local pid
13259         local fid
13260
13261         changelog_register || error "changelog_register failed"
13262
13263         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
13264         # interfer with $MOUNT/.lustre/fid/ access
13265         mkdir $DIR/$tdir
13266         [[ $? -eq 0 ]] || error "mkdir failed"
13267
13268         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
13269         $LCTL set_param fail_loc=0x8000140c
13270         # 5s pause
13271         $LCTL set_param fail_val=5
13272
13273         # create file
13274         echo foofoo > $DIR/$tdir/$tfile &
13275         pid=$!
13276
13277         # wait for create to be delayed
13278         sleep 2
13279
13280         ps -p $pid
13281         [[ $? -eq 0 ]] || error "create should be blocked"
13282
13283         local tempfile=$(mktemp)
13284         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
13285         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
13286         # some delay may occur during ChangeLog publishing and file read just
13287         # above, that could allow file write to happen finally
13288         [[ -s $tempfile ]] && echo "file should be empty"
13289
13290         $LCTL set_param fail_loc=0
13291
13292         wait $pid
13293         [[ $? -eq 0 ]] || error "create failed"
13294 }
13295 run_test 161d "create with concurrent .lustre/fid access"
13296
13297 check_path() {
13298         local expected="$1"
13299         shift
13300         local fid="$2"
13301
13302         local path
13303         path=$($LFS fid2path "$@")
13304         local rc=$?
13305
13306         if [ $rc -ne 0 ]; then
13307                 error "path looked up of '$expected' failed: rc=$rc"
13308         elif [ "$path" != "$expected" ]; then
13309                 error "path looked up '$path' instead of '$expected'"
13310         else
13311                 echo "FID '$fid' resolves to path '$path' as expected"
13312         fi
13313 }
13314
13315 test_162a() { # was test_162
13316         test_mkdir -p -c1 $DIR/$tdir/d2
13317         touch $DIR/$tdir/d2/$tfile
13318         touch $DIR/$tdir/d2/x1
13319         touch $DIR/$tdir/d2/x2
13320         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
13321         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
13322         # regular file
13323         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
13324         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
13325
13326         # softlink
13327         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
13328         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
13329         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
13330
13331         # softlink to wrong file
13332         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
13333         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
13334         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
13335
13336         # hardlink
13337         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
13338         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
13339         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
13340         # fid2path dir/fsname should both work
13341         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
13342         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
13343
13344         # hardlink count: check that there are 2 links
13345         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
13346         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
13347
13348         # hardlink indexing: remove the first link
13349         rm $DIR/$tdir/d2/p/q/r/hlink
13350         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
13351 }
13352 run_test 162a "path lookup sanity"
13353
13354 test_162b() {
13355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13356         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13357
13358         mkdir $DIR/$tdir
13359         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
13360                                 error "create striped dir failed"
13361
13362         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
13363                                         tail -n 1 | awk '{print $2}')
13364         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
13365
13366         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
13367         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
13368
13369         # regular file
13370         for ((i=0;i<5;i++)); do
13371                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
13372                         error "get fid for f$i failed"
13373                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
13374
13375                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
13376                         error "get fid for d$i failed"
13377                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
13378         done
13379
13380         return 0
13381 }
13382 run_test 162b "striped directory path lookup sanity"
13383
13384 # LU-4239: Verify fid2path works with paths 100 or more directories deep
13385 test_162c() {
13386         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
13387                 skip "Need MDS version at least 2.7.51"
13388
13389         local lpath=$tdir.local
13390         local rpath=$tdir.remote
13391
13392         test_mkdir $DIR/$lpath
13393         test_mkdir $DIR/$rpath
13394
13395         for ((i = 0; i <= 101; i++)); do
13396                 lpath="$lpath/$i"
13397                 mkdir $DIR/$lpath
13398                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
13399                         error "get fid for local directory $DIR/$lpath failed"
13400                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
13401
13402                 rpath="$rpath/$i"
13403                 test_mkdir $DIR/$rpath
13404                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
13405                         error "get fid for remote directory $DIR/$rpath failed"
13406                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
13407         done
13408
13409         return 0
13410 }
13411 run_test 162c "fid2path works with paths 100 or more directories deep"
13412
13413 test_169() {
13414         # do directio so as not to populate the page cache
13415         log "creating a 10 Mb file"
13416         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
13417         log "starting reads"
13418         dd if=$DIR/$tfile of=/dev/null bs=4096 &
13419         log "truncating the file"
13420         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
13421         log "killing dd"
13422         kill %+ || true # reads might have finished
13423         echo "wait until dd is finished"
13424         wait
13425         log "removing the temporary file"
13426         rm -rf $DIR/$tfile || error "tmp file removal failed"
13427 }
13428 run_test 169 "parallel read and truncate should not deadlock"
13429
13430 test_170() {
13431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13432
13433         $LCTL clear     # bug 18514
13434         $LCTL debug_daemon start $TMP/${tfile}_log_good
13435         touch $DIR/$tfile
13436         $LCTL debug_daemon stop
13437         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
13438                 error "sed failed to read log_good"
13439
13440         $LCTL debug_daemon start $TMP/${tfile}_log_good
13441         rm -rf $DIR/$tfile
13442         $LCTL debug_daemon stop
13443
13444         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
13445                error "lctl df log_bad failed"
13446
13447         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13448         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13449
13450         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
13451         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
13452
13453         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
13454                 error "bad_line good_line1 good_line2 are empty"
13455
13456         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13457         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
13458         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13459
13460         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
13461         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13462         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13463
13464         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
13465                 error "bad_line_new good_line_new are empty"
13466
13467         local expected_good=$((good_line1 + good_line2*2))
13468
13469         rm -f $TMP/${tfile}*
13470         # LU-231, short malformed line may not be counted into bad lines
13471         if [ $bad_line -ne $bad_line_new ] &&
13472                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
13473                 error "expected $bad_line bad lines, but got $bad_line_new"
13474                 return 1
13475         fi
13476
13477         if [ $expected_good -ne $good_line_new ]; then
13478                 error "expected $expected_good good lines, but got $good_line_new"
13479                 return 2
13480         fi
13481         true
13482 }
13483 run_test 170 "test lctl df to handle corrupted log ====================="
13484
13485 test_171() { # bug20592
13486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13487
13488         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
13489         $LCTL set_param fail_loc=0x50e
13490         $LCTL set_param fail_val=3000
13491         multiop_bg_pause $DIR/$tfile O_s || true
13492         local MULTIPID=$!
13493         kill -USR1 $MULTIPID
13494         # cause log dump
13495         sleep 3
13496         wait $MULTIPID
13497         if dmesg | grep "recursive fault"; then
13498                 error "caught a recursive fault"
13499         fi
13500         $LCTL set_param fail_loc=0
13501         true
13502 }
13503 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
13504
13505 # it would be good to share it with obdfilter-survey/iokit-libecho code
13506 setup_obdecho_osc () {
13507         local rc=0
13508         local ost_nid=$1
13509         local obdfilter_name=$2
13510         echo "Creating new osc for $obdfilter_name on $ost_nid"
13511         # make sure we can find loopback nid
13512         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
13513
13514         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
13515                            ${obdfilter_name}_osc_UUID || rc=2; }
13516         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
13517                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
13518         return $rc
13519 }
13520
13521 cleanup_obdecho_osc () {
13522         local obdfilter_name=$1
13523         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
13524         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
13525         return 0
13526 }
13527
13528 obdecho_test() {
13529         local OBD=$1
13530         local node=$2
13531         local pages=${3:-64}
13532         local rc=0
13533         local id
13534
13535         local count=10
13536         local obd_size=$(get_obd_size $node $OBD)
13537         local page_size=$(get_page_size $node)
13538         if [[ -n "$obd_size" ]]; then
13539                 local new_count=$((obd_size / (pages * page_size / 1024)))
13540                 [[ $new_count -ge $count ]] || count=$new_count
13541         fi
13542
13543         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
13544         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
13545                            rc=2; }
13546         if [ $rc -eq 0 ]; then
13547             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
13548             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
13549         fi
13550         echo "New object id is $id"
13551         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
13552                            rc=4; }
13553         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
13554                            "test_brw $count w v $pages $id" || rc=4; }
13555         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
13556                            rc=4; }
13557         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
13558                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
13559         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
13560                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
13561         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
13562         return $rc
13563 }
13564
13565 test_180a() {
13566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13567
13568         if ! module_loaded obdecho; then
13569                 load_module obdecho/obdecho &&
13570                         stack_trap "rmmod obdecho" EXIT ||
13571                         error "unable to load obdecho on client"
13572         fi
13573
13574         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
13575         local host=$($LCTL get_param -n osc.$osc.import |
13576                      awk '/current_connection:/ { print $2 }' )
13577         local target=$($LCTL get_param -n osc.$osc.import |
13578                        awk '/target:/ { print $2 }' )
13579         target=${target%_UUID}
13580
13581         if [ -n "$target" ]; then
13582                 setup_obdecho_osc $host $target &&
13583                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
13584                         { error "obdecho setup failed with $?"; return; }
13585
13586                 obdecho_test ${target}_osc client ||
13587                         error "obdecho_test failed on ${target}_osc"
13588         else
13589                 $LCTL get_param osc.$osc.import
13590                 error "there is no osc.$osc.import target"
13591         fi
13592 }
13593 run_test 180a "test obdecho on osc"
13594
13595 test_180b() {
13596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13597         remote_ost_nodsh && skip "remote OST with nodsh"
13598
13599         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
13600                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
13601                 error "failed to load module obdecho"
13602
13603         local target=$(do_facet ost1 $LCTL dl |
13604                        awk '/obdfilter/ { print $4; exit; }')
13605
13606         if [ -n "$target" ]; then
13607                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
13608         else
13609                 do_facet ost1 $LCTL dl
13610                 error "there is no obdfilter target on ost1"
13611         fi
13612 }
13613 run_test 180b "test obdecho directly on obdfilter"
13614
13615 test_180c() { # LU-2598
13616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13617         remote_ost_nodsh && skip "remote OST with nodsh"
13618         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
13619                 skip "Need MDS version at least 2.4.0"
13620
13621         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
13622                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
13623                 error "failed to load module obdecho"
13624
13625         local target=$(do_facet ost1 $LCTL dl |
13626                        awk '/obdfilter/ { print $4; exit; }')
13627
13628         if [ -n "$target" ]; then
13629                 local pages=16384 # 64MB bulk I/O RPC size
13630
13631                 obdecho_test "$target" ost1 "$pages" ||
13632                         error "obdecho_test with pages=$pages failed with $?"
13633         else
13634                 do_facet ost1 $LCTL dl
13635                 error "there is no obdfilter target on ost1"
13636         fi
13637 }
13638 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
13639
13640 test_181() { # bug 22177
13641         test_mkdir $DIR/$tdir
13642         # create enough files to index the directory
13643         createmany -o $DIR/$tdir/foobar 4000
13644         # print attributes for debug purpose
13645         lsattr -d .
13646         # open dir
13647         multiop_bg_pause $DIR/$tdir D_Sc || return 1
13648         MULTIPID=$!
13649         # remove the files & current working dir
13650         unlinkmany $DIR/$tdir/foobar 4000
13651         rmdir $DIR/$tdir
13652         kill -USR1 $MULTIPID
13653         wait $MULTIPID
13654         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
13655         return 0
13656 }
13657 run_test 181 "Test open-unlinked dir ========================"
13658
13659 test_182() {
13660         local fcount=1000
13661         local tcount=10
13662
13663         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13664
13665         $LCTL set_param mdc.*.rpc_stats=clear
13666
13667         for (( i = 0; i < $tcount; i++ )) ; do
13668                 mkdir $DIR/$tdir/$i
13669         done
13670
13671         for (( i = 0; i < $tcount; i++ )) ; do
13672                 createmany -o $DIR/$tdir/$i/f- $fcount &
13673         done
13674         wait
13675
13676         for (( i = 0; i < $tcount; i++ )) ; do
13677                 unlinkmany $DIR/$tdir/$i/f- $fcount &
13678         done
13679         wait
13680
13681         $LCTL get_param mdc.*.rpc_stats
13682
13683         rm -rf $DIR/$tdir
13684 }
13685 run_test 182 "Test parallel modify metadata operations ================"
13686
13687 test_183() { # LU-2275
13688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13689         remote_mds_nodsh && skip "remote MDS with nodsh"
13690         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
13691                 skip "Need MDS version at least 2.3.56"
13692
13693         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13694         echo aaa > $DIR/$tdir/$tfile
13695
13696 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
13697         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
13698
13699         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
13700         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
13701
13702         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
13703
13704         # Flush negative dentry cache
13705         touch $DIR/$tdir/$tfile
13706
13707         # We are not checking for any leaked references here, they'll
13708         # become evident next time we do cleanup with module unload.
13709         rm -rf $DIR/$tdir
13710 }
13711 run_test 183 "No crash or request leak in case of strange dispositions ========"
13712
13713 # test suite 184 is for LU-2016, LU-2017
13714 test_184a() {
13715         check_swap_layouts_support
13716
13717         dir0=$DIR/$tdir/$testnum
13718         test_mkdir -p -c1 $dir0
13719         ref1=/etc/passwd
13720         ref2=/etc/group
13721         file1=$dir0/f1
13722         file2=$dir0/f2
13723         $LFS setstripe -c1 $file1
13724         cp $ref1 $file1
13725         $LFS setstripe -c2 $file2
13726         cp $ref2 $file2
13727         gen1=$($LFS getstripe -g $file1)
13728         gen2=$($LFS getstripe -g $file2)
13729
13730         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
13731         gen=$($LFS getstripe -g $file1)
13732         [[ $gen1 != $gen ]] ||
13733                 "Layout generation on $file1 does not change"
13734         gen=$($LFS getstripe -g $file2)
13735         [[ $gen2 != $gen ]] ||
13736                 "Layout generation on $file2 does not change"
13737
13738         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
13739         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
13740
13741         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
13742 }
13743 run_test 184a "Basic layout swap"
13744
13745 test_184b() {
13746         check_swap_layouts_support
13747
13748         dir0=$DIR/$tdir/$testnum
13749         mkdir -p $dir0 || error "creating dir $dir0"
13750         file1=$dir0/f1
13751         file2=$dir0/f2
13752         file3=$dir0/f3
13753         dir1=$dir0/d1
13754         dir2=$dir0/d2
13755         mkdir $dir1 $dir2
13756         $LFS setstripe -c1 $file1
13757         $LFS setstripe -c2 $file2
13758         $LFS setstripe -c1 $file3
13759         chown $RUNAS_ID $file3
13760         gen1=$($LFS getstripe -g $file1)
13761         gen2=$($LFS getstripe -g $file2)
13762
13763         $LFS swap_layouts $dir1 $dir2 &&
13764                 error "swap of directories layouts should fail"
13765         $LFS swap_layouts $dir1 $file1 &&
13766                 error "swap of directory and file layouts should fail"
13767         $RUNAS $LFS swap_layouts $file1 $file2 &&
13768                 error "swap of file we cannot write should fail"
13769         $LFS swap_layouts $file1 $file3 &&
13770                 error "swap of file with different owner should fail"
13771         /bin/true # to clear error code
13772 }
13773 run_test 184b "Forbidden layout swap (will generate errors)"
13774
13775 test_184c() {
13776         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
13777         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
13778         check_swap_layouts_support
13779
13780         local dir0=$DIR/$tdir/$testnum
13781         mkdir -p $dir0 || error "creating dir $dir0"
13782
13783         local ref1=$dir0/ref1
13784         local ref2=$dir0/ref2
13785         local file1=$dir0/file1
13786         local file2=$dir0/file2
13787         # create a file large enough for the concurrent test
13788         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
13789         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
13790         echo "ref file size: ref1($(stat -c %s $ref1))," \
13791              "ref2($(stat -c %s $ref2))"
13792
13793         cp $ref2 $file2
13794         dd if=$ref1 of=$file1 bs=16k &
13795         local DD_PID=$!
13796
13797         # Make sure dd starts to copy file
13798         while [ ! -f $file1 ]; do sleep 0.1; done
13799
13800         $LFS swap_layouts $file1 $file2
13801         local rc=$?
13802         wait $DD_PID
13803         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
13804         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
13805
13806         # how many bytes copied before swapping layout
13807         local copied=$(stat -c %s $file2)
13808         local remaining=$(stat -c %s $ref1)
13809         remaining=$((remaining - copied))
13810         echo "Copied $copied bytes before swapping layout..."
13811
13812         cmp -n $copied $file1 $ref2 | grep differ &&
13813                 error "Content mismatch [0, $copied) of ref2 and file1"
13814         cmp -n $copied $file2 $ref1 ||
13815                 error "Content mismatch [0, $copied) of ref1 and file2"
13816         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
13817                 error "Content mismatch [$copied, EOF) of ref1 and file1"
13818
13819         # clean up
13820         rm -f $ref1 $ref2 $file1 $file2
13821 }
13822 run_test 184c "Concurrent write and layout swap"
13823
13824 test_184d() {
13825         check_swap_layouts_support
13826         [ -z "$(which getfattr 2>/dev/null)" ] &&
13827                 skip_env "no getfattr command"
13828
13829         local file1=$DIR/$tdir/$tfile-1
13830         local file2=$DIR/$tdir/$tfile-2
13831         local file3=$DIR/$tdir/$tfile-3
13832         local lovea1
13833         local lovea2
13834
13835         mkdir -p $DIR/$tdir
13836         touch $file1 || error "create $file1 failed"
13837         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
13838                 error "create $file2 failed"
13839         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
13840                 error "create $file3 failed"
13841         lovea1=$(get_layout_param $file1)
13842
13843         $LFS swap_layouts $file2 $file3 ||
13844                 error "swap $file2 $file3 layouts failed"
13845         $LFS swap_layouts $file1 $file2 ||
13846                 error "swap $file1 $file2 layouts failed"
13847
13848         lovea2=$(get_layout_param $file2)
13849         echo "$lovea1"
13850         echo "$lovea2"
13851         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
13852
13853         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
13854         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
13855 }
13856 run_test 184d "allow stripeless layouts swap"
13857
13858 test_184e() {
13859         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
13860                 skip "Need MDS version at least 2.6.94"
13861         check_swap_layouts_support
13862         [ -z "$(which getfattr 2>/dev/null)" ] &&
13863                 skip_env "no getfattr command"
13864
13865         local file1=$DIR/$tdir/$tfile-1
13866         local file2=$DIR/$tdir/$tfile-2
13867         local file3=$DIR/$tdir/$tfile-3
13868         local lovea
13869
13870         mkdir -p $DIR/$tdir
13871         touch $file1 || error "create $file1 failed"
13872         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
13873                 error "create $file2 failed"
13874         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
13875                 error "create $file3 failed"
13876
13877         $LFS swap_layouts $file1 $file2 ||
13878                 error "swap $file1 $file2 layouts failed"
13879
13880         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
13881         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
13882
13883         echo 123 > $file1 || error "Should be able to write into $file1"
13884
13885         $LFS swap_layouts $file1 $file3 ||
13886                 error "swap $file1 $file3 layouts failed"
13887
13888         echo 123 > $file1 || error "Should be able to write into $file1"
13889
13890         rm -rf $file1 $file2 $file3
13891 }
13892 run_test 184e "Recreate layout after stripeless layout swaps"
13893
13894 test_184f() {
13895         # Create a file with name longer than sizeof(struct stat) ==
13896         # 144 to see if we can get chars from the file name to appear
13897         # in the returned striping. Note that 'f' == 0x66.
13898         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
13899
13900         mkdir -p $DIR/$tdir
13901         mcreate $DIR/$tdir/$file
13902         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
13903                 error "IOC_MDC_GETFILEINFO returned garbage striping"
13904         fi
13905 }
13906 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
13907
13908 test_185() { # LU-2441
13909         # LU-3553 - no volatile file support in old servers
13910         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
13911                 skip "Need MDS version at least 2.3.60"
13912
13913         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13914         touch $DIR/$tdir/spoo
13915         local mtime1=$(stat -c "%Y" $DIR/$tdir)
13916         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
13917                 error "cannot create/write a volatile file"
13918         [ "$FILESET" == "" ] &&
13919         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
13920                 error "FID is still valid after close"
13921
13922         multiop_bg_pause $DIR/$tdir vVw4096_c
13923         local multi_pid=$!
13924
13925         local OLD_IFS=$IFS
13926         IFS=":"
13927         local fidv=($fid)
13928         IFS=$OLD_IFS
13929         # assume that the next FID for this client is sequential, since stdout
13930         # is unfortunately eaten by multiop_bg_pause
13931         local n=$((${fidv[1]} + 1))
13932         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
13933         if [ "$FILESET" == "" ]; then
13934                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
13935                         error "FID is missing before close"
13936         fi
13937         kill -USR1 $multi_pid
13938         # 1 second delay, so if mtime change we will see it
13939         sleep 1
13940         local mtime2=$(stat -c "%Y" $DIR/$tdir)
13941         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
13942 }
13943 run_test 185 "Volatile file support"
13944
13945 test_187a() {
13946         remote_mds_nodsh && skip "remote MDS with nodsh"
13947         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
13948                 skip "Need MDS version at least 2.3.0"
13949
13950         local dir0=$DIR/$tdir/$testnum
13951         mkdir -p $dir0 || error "creating dir $dir0"
13952
13953         local file=$dir0/file1
13954         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
13955         local dv1=$($LFS data_version $file)
13956         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
13957         local dv2=$($LFS data_version $file)
13958         [[ $dv1 != $dv2 ]] ||
13959                 error "data version did not change on write $dv1 == $dv2"
13960
13961         # clean up
13962         rm -f $file1
13963 }
13964 run_test 187a "Test data version change"
13965
13966 test_187b() {
13967         remote_mds_nodsh && skip "remote MDS with nodsh"
13968         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
13969                 skip "Need MDS version at least 2.3.0"
13970
13971         local dir0=$DIR/$tdir/$testnum
13972         mkdir -p $dir0 || error "creating dir $dir0"
13973
13974         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
13975         [[ ${DV[0]} != ${DV[1]} ]] ||
13976                 error "data version did not change on write"\
13977                       " ${DV[0]} == ${DV[1]}"
13978
13979         # clean up
13980         rm -f $file1
13981 }
13982 run_test 187b "Test data version change on volatile file"
13983
13984 test_200() {
13985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13986         remote_mgs_nodsh && skip "remote MGS with nodsh"
13987         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13988
13989         local POOL=${POOL:-cea1}
13990         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
13991         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
13992         # Pool OST targets
13993         local first_ost=0
13994         local last_ost=$(($OSTCOUNT - 1))
13995         local ost_step=2
13996         local ost_list=$(seq $first_ost $ost_step $last_ost)
13997         local ost_range="$first_ost $last_ost $ost_step"
13998         local test_path=$POOL_ROOT/$POOL_DIR_NAME
13999         local file_dir=$POOL_ROOT/file_tst
14000         local subdir=$test_path/subdir
14001         local rc=0
14002
14003         if ! combined_mgs_mds ; then
14004                 mount_mgs_client
14005         fi
14006
14007         while : ; do
14008                 # former test_200a test_200b
14009                 pool_add $POOL                          || { rc=$? ; break; }
14010                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
14011                 # former test_200c test_200d
14012                 mkdir -p $test_path
14013                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
14014                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
14015                 mkdir -p $subdir
14016                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
14017                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
14018                                                         || { rc=$? ; break; }
14019                 # former test_200e test_200f
14020                 local files=$((OSTCOUNT*3))
14021                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
14022                                                         || { rc=$? ; break; }
14023                 pool_create_files $POOL $file_dir $files "$ost_list" \
14024                                                         || { rc=$? ; break; }
14025                 # former test_200g test_200h
14026                 pool_lfs_df $POOL                       || { rc=$? ; break; }
14027                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
14028
14029                 # former test_201a test_201b test_201c
14030                 pool_remove_first_target $POOL          || { rc=$? ; break; }
14031
14032                 local f=$test_path/$tfile
14033                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
14034                 pool_remove $POOL $f                    || { rc=$? ; break; }
14035                 break
14036         done
14037
14038         destroy_test_pools
14039
14040         if ! combined_mgs_mds ; then
14041                 umount_mgs_client
14042         fi
14043         return $rc
14044 }
14045 run_test 200 "OST pools"
14046
14047 # usage: default_attr <count | size | offset>
14048 default_attr() {
14049         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
14050 }
14051
14052 # usage: check_default_stripe_attr
14053 check_default_stripe_attr() {
14054         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
14055         case $1 in
14056         --stripe-count|-c)
14057                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
14058         --stripe-size|-S)
14059                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
14060         --stripe-index|-i)
14061                 EXPECTED=-1;;
14062         *)
14063                 error "unknown getstripe attr '$1'"
14064         esac
14065
14066         [ $ACTUAL == $EXPECTED ] ||
14067                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
14068 }
14069
14070 test_204a() {
14071         test_mkdir $DIR/$tdir
14072         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
14073
14074         check_default_stripe_attr --stripe-count
14075         check_default_stripe_attr --stripe-size
14076         check_default_stripe_attr --stripe-index
14077 }
14078 run_test 204a "Print default stripe attributes"
14079
14080 test_204b() {
14081         test_mkdir $DIR/$tdir
14082         $LFS setstripe --stripe-count 1 $DIR/$tdir
14083
14084         check_default_stripe_attr --stripe-size
14085         check_default_stripe_attr --stripe-index
14086 }
14087 run_test 204b "Print default stripe size and offset"
14088
14089 test_204c() {
14090         test_mkdir $DIR/$tdir
14091         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14092
14093         check_default_stripe_attr --stripe-count
14094         check_default_stripe_attr --stripe-index
14095 }
14096 run_test 204c "Print default stripe count and offset"
14097
14098 test_204d() {
14099         test_mkdir $DIR/$tdir
14100         $LFS setstripe --stripe-index 0 $DIR/$tdir
14101
14102         check_default_stripe_attr --stripe-count
14103         check_default_stripe_attr --stripe-size
14104 }
14105 run_test 204d "Print default stripe count and size"
14106
14107 test_204e() {
14108         test_mkdir $DIR/$tdir
14109         $LFS setstripe -d $DIR/$tdir
14110
14111         check_default_stripe_attr --stripe-count --raw
14112         check_default_stripe_attr --stripe-size --raw
14113         check_default_stripe_attr --stripe-index --raw
14114 }
14115 run_test 204e "Print raw stripe attributes"
14116
14117 test_204f() {
14118         test_mkdir $DIR/$tdir
14119         $LFS setstripe --stripe-count 1 $DIR/$tdir
14120
14121         check_default_stripe_attr --stripe-size --raw
14122         check_default_stripe_attr --stripe-index --raw
14123 }
14124 run_test 204f "Print raw stripe size and offset"
14125
14126 test_204g() {
14127         test_mkdir $DIR/$tdir
14128         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14129
14130         check_default_stripe_attr --stripe-count --raw
14131         check_default_stripe_attr --stripe-index --raw
14132 }
14133 run_test 204g "Print raw stripe count and offset"
14134
14135 test_204h() {
14136         test_mkdir $DIR/$tdir
14137         $LFS setstripe --stripe-index 0 $DIR/$tdir
14138
14139         check_default_stripe_attr --stripe-count --raw
14140         check_default_stripe_attr --stripe-size --raw
14141 }
14142 run_test 204h "Print raw stripe count and size"
14143
14144 # Figure out which job scheduler is being used, if any,
14145 # or use a fake one
14146 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
14147         JOBENV=SLURM_JOB_ID
14148 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
14149         JOBENV=LSB_JOBID
14150 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
14151         JOBENV=PBS_JOBID
14152 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
14153         JOBENV=LOADL_STEP_ID
14154 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
14155         JOBENV=JOB_ID
14156 else
14157         $LCTL list_param jobid_name > /dev/null 2>&1
14158         if [ $? -eq 0 ]; then
14159                 JOBENV=nodelocal
14160         else
14161                 JOBENV=FAKE_JOBID
14162         fi
14163 fi
14164 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
14165
14166 verify_jobstats() {
14167         local cmd=($1)
14168         shift
14169         local facets="$@"
14170
14171 # we don't really need to clear the stats for this test to work, since each
14172 # command has a unique jobid, but it makes debugging easier if needed.
14173 #       for facet in $facets; do
14174 #               local dev=$(convert_facet2label $facet)
14175 #               # clear old jobstats
14176 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
14177 #       done
14178
14179         # use a new JobID for each test, or we might see an old one
14180         [ "$JOBENV" = "FAKE_JOBID" ] &&
14181                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
14182
14183         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
14184
14185         [ "$JOBENV" = "nodelocal" ] && {
14186                 FAKE_JOBID=id.$testnum.%e.$RANDOM
14187                 $LCTL set_param jobid_name=$FAKE_JOBID
14188                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
14189         }
14190
14191         log "Test: ${cmd[*]}"
14192         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
14193
14194         if [ $JOBENV = "FAKE_JOBID" ]; then
14195                 FAKE_JOBID=$JOBVAL ${cmd[*]}
14196         else
14197                 ${cmd[*]}
14198         fi
14199
14200         # all files are created on OST0000
14201         for facet in $facets; do
14202                 local stats="*.$(convert_facet2label $facet).job_stats"
14203
14204                 # strip out libtool wrappers for in-tree executables
14205                 if [ $(do_facet $facet lctl get_param $stats |
14206                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
14207                         do_facet $facet lctl get_param $stats
14208                         error "No jobstats for $JOBVAL found on $facet::$stats"
14209                 fi
14210         done
14211 }
14212
14213 jobstats_set() {
14214         local new_jobenv=$1
14215
14216         set_persistent_param_and_check client "jobid_var" \
14217                 "$FSNAME.sys.jobid_var" $new_jobenv
14218 }
14219
14220 test_205() { # Job stats
14221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14222         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
14223                 skip "Need MDS version with at least 2.7.1"
14224         remote_mgs_nodsh && skip "remote MGS with nodsh"
14225         remote_mds_nodsh && skip "remote MDS with nodsh"
14226         remote_ost_nodsh && skip "remote OST with nodsh"
14227         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
14228                 skip "Server doesn't support jobstats"
14229         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
14230
14231         local old_jobenv=$($LCTL get_param -n jobid_var)
14232         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
14233
14234         if [[ $PERM_CMD == *"set_param -P"* ]]; then
14235                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
14236         else
14237                 stack_trap "do_facet mgs $PERM_CMD \
14238                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
14239         fi
14240         changelog_register
14241
14242         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
14243                                 mdt.*.job_cleanup_interval | head -n 1)
14244         local new_interval=5
14245         do_facet $SINGLEMDS \
14246                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
14247         stack_trap "do_facet $SINGLEMDS \
14248                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
14249         local start=$SECONDS
14250
14251         local cmd
14252         # mkdir
14253         cmd="mkdir $DIR/$tdir"
14254         verify_jobstats "$cmd" "$SINGLEMDS"
14255         # rmdir
14256         cmd="rmdir $DIR/$tdir"
14257         verify_jobstats "$cmd" "$SINGLEMDS"
14258         # mkdir on secondary MDT
14259         if [ $MDSCOUNT -gt 1 ]; then
14260                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
14261                 verify_jobstats "$cmd" "mds2"
14262         fi
14263         # mknod
14264         cmd="mknod $DIR/$tfile c 1 3"
14265         verify_jobstats "$cmd" "$SINGLEMDS"
14266         # unlink
14267         cmd="rm -f $DIR/$tfile"
14268         verify_jobstats "$cmd" "$SINGLEMDS"
14269         # create all files on OST0000 so verify_jobstats can find OST stats
14270         # open & close
14271         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
14272         verify_jobstats "$cmd" "$SINGLEMDS"
14273         # setattr
14274         cmd="touch $DIR/$tfile"
14275         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14276         # write
14277         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
14278         verify_jobstats "$cmd" "ost1"
14279         # read
14280         cancel_lru_locks osc
14281         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
14282         verify_jobstats "$cmd" "ost1"
14283         # truncate
14284         cmd="$TRUNCATE $DIR/$tfile 0"
14285         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14286         # rename
14287         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
14288         verify_jobstats "$cmd" "$SINGLEMDS"
14289         # jobstats expiry - sleep until old stats should be expired
14290         local left=$((new_interval + 5 - (SECONDS - start)))
14291         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
14292                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
14293                         "0" $left
14294         cmd="mkdir $DIR/$tdir.expire"
14295         verify_jobstats "$cmd" "$SINGLEMDS"
14296         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
14297             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
14298
14299         # Ensure that jobid are present in changelog (if supported by MDS)
14300         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
14301                 changelog_dump | tail -10
14302                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
14303                 [ $jobids -eq 9 ] ||
14304                         error "Wrong changelog jobid count $jobids != 9"
14305
14306                 # LU-5862
14307                 JOBENV="disable"
14308                 jobstats_set $JOBENV
14309                 touch $DIR/$tfile
14310                 changelog_dump | grep $tfile
14311                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
14312                 [ $jobids -eq 0 ] ||
14313                         error "Unexpected jobids when jobid_var=$JOBENV"
14314         fi
14315
14316         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
14317         JOBENV="JOBCOMPLEX"
14318         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
14319
14320         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
14321 }
14322 run_test 205 "Verify job stats"
14323
14324 # LU-1480, LU-1773 and LU-1657
14325 test_206() {
14326         mkdir -p $DIR/$tdir
14327         $LFS setstripe -c -1 $DIR/$tdir
14328 #define OBD_FAIL_LOV_INIT 0x1403
14329         $LCTL set_param fail_loc=0xa0001403
14330         $LCTL set_param fail_val=1
14331         touch $DIR/$tdir/$tfile || true
14332 }
14333 run_test 206 "fail lov_init_raid0() doesn't lbug"
14334
14335 test_207a() {
14336         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14337         local fsz=`stat -c %s $DIR/$tfile`
14338         cancel_lru_locks mdc
14339
14340         # do not return layout in getattr intent
14341 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
14342         $LCTL set_param fail_loc=0x170
14343         local sz=`stat -c %s $DIR/$tfile`
14344
14345         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
14346
14347         rm -rf $DIR/$tfile
14348 }
14349 run_test 207a "can refresh layout at glimpse"
14350
14351 test_207b() {
14352         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14353         local cksum=`md5sum $DIR/$tfile`
14354         local fsz=`stat -c %s $DIR/$tfile`
14355         cancel_lru_locks mdc
14356         cancel_lru_locks osc
14357
14358         # do not return layout in getattr intent
14359 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
14360         $LCTL set_param fail_loc=0x171
14361
14362         # it will refresh layout after the file is opened but before read issues
14363         echo checksum is "$cksum"
14364         echo "$cksum" |md5sum -c --quiet || error "file differs"
14365
14366         rm -rf $DIR/$tfile
14367 }
14368 run_test 207b "can refresh layout at open"
14369
14370 test_208() {
14371         # FIXME: in this test suite, only RD lease is used. This is okay
14372         # for now as only exclusive open is supported. After generic lease
14373         # is done, this test suite should be revised. - Jinshan
14374
14375         remote_mds_nodsh && skip "remote MDS with nodsh"
14376         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
14377                 skip "Need MDS version at least 2.4.52"
14378
14379         echo "==== test 1: verify get lease work"
14380         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
14381
14382         echo "==== test 2: verify lease can be broken by upcoming open"
14383         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14384         local PID=$!
14385         sleep 1
14386
14387         $MULTIOP $DIR/$tfile oO_RDONLY:c
14388         kill -USR1 $PID && wait $PID || error "break lease error"
14389
14390         echo "==== test 3: verify lease can't be granted if an open already exists"
14391         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
14392         local PID=$!
14393         sleep 1
14394
14395         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
14396         kill -USR1 $PID && wait $PID || error "open file error"
14397
14398         echo "==== test 4: lease can sustain over recovery"
14399         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
14400         PID=$!
14401         sleep 1
14402
14403         fail mds1
14404
14405         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
14406
14407         echo "==== test 5: lease broken can't be regained by replay"
14408         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14409         PID=$!
14410         sleep 1
14411
14412         # open file to break lease and then recovery
14413         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
14414         fail mds1
14415
14416         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
14417
14418         rm -f $DIR/$tfile
14419 }
14420 run_test 208 "Exclusive open"
14421
14422 test_209() {
14423         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
14424                 skip_env "must have disp_stripe"
14425
14426         touch $DIR/$tfile
14427         sync; sleep 5; sync;
14428
14429         echo 3 > /proc/sys/vm/drop_caches
14430         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14431
14432         # open/close 500 times
14433         for i in $(seq 500); do
14434                 cat $DIR/$tfile
14435         done
14436
14437         echo 3 > /proc/sys/vm/drop_caches
14438         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14439
14440         echo "before: $req_before, after: $req_after"
14441         [ $((req_after - req_before)) -ge 300 ] &&
14442                 error "open/close requests are not freed"
14443         return 0
14444 }
14445 run_test 209 "read-only open/close requests should be freed promptly"
14446
14447 test_212() {
14448         size=`date +%s`
14449         size=$((size % 8192 + 1))
14450         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
14451         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
14452         rm -f $DIR/f212 $DIR/f212.xyz
14453 }
14454 run_test 212 "Sendfile test ============================================"
14455
14456 test_213() {
14457         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
14458         cancel_lru_locks osc
14459         lctl set_param fail_loc=0x8000040f
14460         # generate a read lock
14461         cat $DIR/$tfile > /dev/null
14462         # write to the file, it will try to cancel the above read lock.
14463         cat /etc/hosts >> $DIR/$tfile
14464 }
14465 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
14466
14467 test_214() { # for bug 20133
14468         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
14469         for (( i=0; i < 340; i++ )) ; do
14470                 touch $DIR/$tdir/d214c/a$i
14471         done
14472
14473         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
14474         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
14475         ls $DIR/d214c || error "ls $DIR/d214c failed"
14476         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
14477         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
14478 }
14479 run_test 214 "hash-indexed directory test - bug 20133"
14480
14481 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
14482 create_lnet_proc_files() {
14483         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
14484 }
14485
14486 # counterpart of create_lnet_proc_files
14487 remove_lnet_proc_files() {
14488         rm -f $TMP/lnet_$1.sys
14489 }
14490
14491 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14492 # 3rd arg as regexp for body
14493 check_lnet_proc_stats() {
14494         local l=$(cat "$TMP/lnet_$1" |wc -l)
14495         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
14496
14497         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
14498 }
14499
14500 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14501 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
14502 # optional and can be regexp for 2nd line (lnet.routes case)
14503 check_lnet_proc_entry() {
14504         local blp=2          # blp stands for 'position of 1st line of body'
14505         [ -z "$5" ] || blp=3 # lnet.routes case
14506
14507         local l=$(cat "$TMP/lnet_$1" |wc -l)
14508         # subtracting one from $blp because the body can be empty
14509         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
14510
14511         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
14512                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
14513
14514         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
14515                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
14516
14517         # bail out if any unexpected line happened
14518         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
14519         [ "$?" != 0 ] || error "$2 misformatted"
14520 }
14521
14522 test_215() { # for bugs 18102, 21079, 21517
14523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14524
14525         local N='(0|[1-9][0-9]*)'       # non-negative numeric
14526         local P='[1-9][0-9]*'           # positive numeric
14527         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
14528         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
14529         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
14530         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
14531
14532         local L1 # regexp for 1st line
14533         local L2 # regexp for 2nd line (optional)
14534         local BR # regexp for the rest (body)
14535
14536         # lnet.stats should look as 11 space-separated non-negative numerics
14537         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
14538         create_lnet_proc_files "stats"
14539         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
14540         remove_lnet_proc_files "stats"
14541
14542         # lnet.routes should look like this:
14543         # Routing disabled/enabled
14544         # net hops priority state router
14545         # where net is a string like tcp0, hops > 0, priority >= 0,
14546         # state is up/down,
14547         # router is a string like 192.168.1.1@tcp2
14548         L1="^Routing (disabled|enabled)$"
14549         L2="^net +hops +priority +state +router$"
14550         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
14551         create_lnet_proc_files "routes"
14552         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
14553         remove_lnet_proc_files "routes"
14554
14555         # lnet.routers should look like this:
14556         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
14557         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
14558         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
14559         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
14560         L1="^ref +rtr_ref +alive_cnt +state +last_ping +ping_sent +deadline +down_ni +router$"
14561         BR="^$P +$P +$N +(up|down) +$N +(0|1) +$I +$I +$NID$"
14562         create_lnet_proc_files "routers"
14563         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
14564         remove_lnet_proc_files "routers"
14565
14566         # lnet.peers should look like this:
14567         # nid refs state last max rtr min tx min queue
14568         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
14569         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
14570         # numeric (0 or >0 or <0), queue >= 0.
14571         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
14572         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
14573         create_lnet_proc_files "peers"
14574         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
14575         remove_lnet_proc_files "peers"
14576
14577         # lnet.buffers  should look like this:
14578         # pages count credits min
14579         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
14580         L1="^pages +count +credits +min$"
14581         BR="^ +$N +$N +$I +$I$"
14582         create_lnet_proc_files "buffers"
14583         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
14584         remove_lnet_proc_files "buffers"
14585
14586         # lnet.nis should look like this:
14587         # nid status alive refs peer rtr max tx min
14588         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
14589         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
14590         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
14591         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
14592         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
14593         create_lnet_proc_files "nis"
14594         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
14595         remove_lnet_proc_files "nis"
14596
14597         # can we successfully write to lnet.stats?
14598         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
14599 }
14600 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
14601
14602 test_216() { # bug 20317
14603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14604         remote_ost_nodsh && skip "remote OST with nodsh"
14605
14606         local node
14607         local facets=$(get_facets OST)
14608         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14609
14610         save_lustre_params client "osc.*.contention_seconds" > $p
14611         save_lustre_params $facets \
14612                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
14613         save_lustre_params $facets \
14614                 "ldlm.namespaces.filter-*.contended_locks" >> $p
14615         save_lustre_params $facets \
14616                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
14617         clear_stats osc.*.osc_stats
14618
14619         # agressive lockless i/o settings
14620         do_nodes $(comma_list $(osts_nodes)) \
14621                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
14622                         ldlm.namespaces.filter-*.contended_locks=0 \
14623                         ldlm.namespaces.filter-*.contention_seconds=60"
14624         lctl set_param -n osc.*.contention_seconds=60
14625
14626         $DIRECTIO write $DIR/$tfile 0 10 4096
14627         $CHECKSTAT -s 40960 $DIR/$tfile
14628
14629         # disable lockless i/o
14630         do_nodes $(comma_list $(osts_nodes)) \
14631                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
14632                         ldlm.namespaces.filter-*.contended_locks=32 \
14633                         ldlm.namespaces.filter-*.contention_seconds=0"
14634         lctl set_param -n osc.*.contention_seconds=0
14635         clear_stats osc.*.osc_stats
14636
14637         dd if=/dev/zero of=$DIR/$tfile count=0
14638         $CHECKSTAT -s 0 $DIR/$tfile
14639
14640         restore_lustre_params <$p
14641         rm -f $p
14642         rm $DIR/$tfile
14643 }
14644 run_test 216 "check lockless direct write updates file size and kms correctly"
14645
14646 test_217() { # bug 22430
14647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14648
14649         local node
14650         local nid
14651
14652         for node in $(nodes_list); do
14653                 nid=$(host_nids_address $node $NETTYPE)
14654                 if [[ $nid = *-* ]] ; then
14655                         echo "lctl ping $(h2nettype $nid)"
14656                         lctl ping $(h2nettype $nid)
14657                 else
14658                         echo "skipping $node (no hyphen detected)"
14659                 fi
14660         done
14661 }
14662 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
14663
14664 test_218() {
14665        # do directio so as not to populate the page cache
14666        log "creating a 10 Mb file"
14667        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
14668        log "starting reads"
14669        dd if=$DIR/$tfile of=/dev/null bs=4096 &
14670        log "truncating the file"
14671        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
14672        log "killing dd"
14673        kill %+ || true # reads might have finished
14674        echo "wait until dd is finished"
14675        wait
14676        log "removing the temporary file"
14677        rm -rf $DIR/$tfile || error "tmp file removal failed"
14678 }
14679 run_test 218 "parallel read and truncate should not deadlock"
14680
14681 test_219() {
14682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14683
14684         # write one partial page
14685         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
14686         # set no grant so vvp_io_commit_write will do sync write
14687         $LCTL set_param fail_loc=0x411
14688         # write a full page at the end of file
14689         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
14690
14691         $LCTL set_param fail_loc=0
14692         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
14693         $LCTL set_param fail_loc=0x411
14694         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
14695
14696         # LU-4201
14697         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
14698         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
14699 }
14700 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
14701
14702 test_220() { #LU-325
14703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14704         remote_ost_nodsh && skip "remote OST with nodsh"
14705         remote_mds_nodsh && skip "remote MDS with nodsh"
14706         remote_mgs_nodsh && skip "remote MGS with nodsh"
14707
14708         local OSTIDX=0
14709
14710         # create on MDT0000 so the last_id and next_id are correct
14711         mkdir $DIR/$tdir
14712         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
14713         OST=${OST%_UUID}
14714
14715         # on the mdt's osc
14716         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
14717         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
14718                         osc.$mdtosc_proc1.prealloc_last_id)
14719         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
14720                         osc.$mdtosc_proc1.prealloc_next_id)
14721
14722         $LFS df -i
14723
14724         if ! combined_mgs_mds ; then
14725                 mount_mgs_client
14726         fi
14727
14728         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
14729         #define OBD_FAIL_OST_ENOINO              0x229
14730         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
14731         create_pool $FSNAME.$TESTNAME || return 1
14732         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
14733
14734         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
14735
14736         MDSOBJS=$((last_id - next_id))
14737         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
14738
14739         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
14740         echo "OST still has $count kbytes free"
14741
14742         echo "create $MDSOBJS files @next_id..."
14743         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
14744
14745         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
14746                         osc.$mdtosc_proc1.prealloc_last_id)
14747         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
14748                         osc.$mdtosc_proc1.prealloc_next_id)
14749
14750         echo "after creation, last_id=$last_id2, next_id=$next_id2"
14751         $LFS df -i
14752
14753         echo "cleanup..."
14754
14755         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
14756         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
14757
14758         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
14759                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
14760         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
14761                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
14762         echo "unlink $MDSOBJS files @$next_id..."
14763         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
14764
14765         if ! combined_mgs_mds ; then
14766                 umount_mgs_client
14767         fi
14768 }
14769 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
14770
14771 test_221() {
14772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14773
14774         dd if=`which date` of=$MOUNT/date oflag=sync
14775         chmod +x $MOUNT/date
14776
14777         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
14778         $LCTL set_param fail_loc=0x80001401
14779
14780         $MOUNT/date > /dev/null
14781         rm -f $MOUNT/date
14782 }
14783 run_test 221 "make sure fault and truncate race to not cause OOM"
14784
14785 test_222a () {
14786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14787
14788         rm -rf $DIR/$tdir
14789         test_mkdir $DIR/$tdir
14790         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14791         createmany -o $DIR/$tdir/$tfile 10
14792         cancel_lru_locks mdc
14793         cancel_lru_locks osc
14794         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
14795         $LCTL set_param fail_loc=0x31a
14796         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
14797         $LCTL set_param fail_loc=0
14798         rm -r $DIR/$tdir
14799 }
14800 run_test 222a "AGL for ls should not trigger CLIO lock failure"
14801
14802 test_222b () {
14803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14804
14805         rm -rf $DIR/$tdir
14806         test_mkdir $DIR/$tdir
14807         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14808         createmany -o $DIR/$tdir/$tfile 10
14809         cancel_lru_locks mdc
14810         cancel_lru_locks osc
14811         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
14812         $LCTL set_param fail_loc=0x31a
14813         rm -r $DIR/$tdir || error "AGL for rmdir failed"
14814         $LCTL set_param fail_loc=0
14815 }
14816 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
14817
14818 test_223 () {
14819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14820
14821         rm -rf $DIR/$tdir
14822         test_mkdir $DIR/$tdir
14823         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14824         createmany -o $DIR/$tdir/$tfile 10
14825         cancel_lru_locks mdc
14826         cancel_lru_locks osc
14827         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
14828         $LCTL set_param fail_loc=0x31b
14829         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
14830         $LCTL set_param fail_loc=0
14831         rm -r $DIR/$tdir
14832 }
14833 run_test 223 "osc reenqueue if without AGL lock granted ======================="
14834
14835 test_224a() { # LU-1039, MRP-303
14836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14837
14838         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
14839         $LCTL set_param fail_loc=0x508
14840         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
14841         $LCTL set_param fail_loc=0
14842         df $DIR
14843 }
14844 run_test 224a "Don't panic on bulk IO failure"
14845
14846 test_224b() { # LU-1039, MRP-303
14847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14848
14849         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
14850         cancel_lru_locks osc
14851         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
14852         $LCTL set_param fail_loc=0x515
14853         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
14854         $LCTL set_param fail_loc=0
14855         df $DIR
14856 }
14857 run_test 224b "Don't panic on bulk IO failure"
14858
14859 test_224c() { # LU-6441
14860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14861         remote_mds_nodsh && skip "remote MDS with nodsh"
14862
14863         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14864         save_writethrough $p
14865         set_cache writethrough on
14866
14867         local pages_per_rpc=$($LCTL get_param \
14868                                 osc.*.max_pages_per_rpc)
14869         local at_max=$($LCTL get_param -n at_max)
14870         local timeout=$($LCTL get_param -n timeout)
14871         local test_at="at_max"
14872         local param_at="$FSNAME.sys.at_max"
14873         local test_timeout="timeout"
14874         local param_timeout="$FSNAME.sys.timeout"
14875
14876         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
14877
14878         set_persistent_param_and_check client "$test_at" "$param_at" 0
14879         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
14880
14881         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
14882         do_facet ost1 "$LCTL set_param fail_loc=0x520"
14883         $LFS setstripe -c 1 -i 0 $DIR/$tfile
14884         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
14885         sync
14886         do_facet ost1 "$LCTL set_param fail_loc=0"
14887
14888         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
14889         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
14890                 $timeout
14891
14892         $LCTL set_param -n $pages_per_rpc
14893         restore_lustre_params < $p
14894         rm -f $p
14895 }
14896 run_test 224c "Don't hang if one of md lost during large bulk RPC"
14897
14898 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
14899 test_225a () {
14900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14901         if [ -z ${MDSSURVEY} ]; then
14902                 skip_env "mds-survey not found"
14903         fi
14904         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
14905                 skip "Need MDS version at least 2.2.51"
14906
14907         local mds=$(facet_host $SINGLEMDS)
14908         local target=$(do_nodes $mds 'lctl dl' |
14909                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
14910
14911         local cmd1="file_count=1000 thrhi=4"
14912         local cmd2="dir_count=2 layer=mdd stripe_count=0"
14913         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
14914         local cmd="$cmd1 $cmd2 $cmd3"
14915
14916         rm -f ${TMP}/mds_survey*
14917         echo + $cmd
14918         eval $cmd || error "mds-survey with zero-stripe failed"
14919         cat ${TMP}/mds_survey*
14920         rm -f ${TMP}/mds_survey*
14921 }
14922 run_test 225a "Metadata survey sanity with zero-stripe"
14923
14924 test_225b () {
14925         if [ -z ${MDSSURVEY} ]; then
14926                 skip_env "mds-survey not found"
14927         fi
14928         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
14929                 skip "Need MDS version at least 2.2.51"
14930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14931         remote_mds_nodsh && skip "remote MDS with nodsh"
14932         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
14933                 skip_env "Need to mount OST to test"
14934         fi
14935
14936         local mds=$(facet_host $SINGLEMDS)
14937         local target=$(do_nodes $mds 'lctl dl' |
14938                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
14939
14940         local cmd1="file_count=1000 thrhi=4"
14941         local cmd2="dir_count=2 layer=mdd stripe_count=1"
14942         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
14943         local cmd="$cmd1 $cmd2 $cmd3"
14944
14945         rm -f ${TMP}/mds_survey*
14946         echo + $cmd
14947         eval $cmd || error "mds-survey with stripe_count failed"
14948         cat ${TMP}/mds_survey*
14949         rm -f ${TMP}/mds_survey*
14950 }
14951 run_test 225b "Metadata survey sanity with stripe_count = 1"
14952
14953 mcreate_path2fid () {
14954         local mode=$1
14955         local major=$2
14956         local minor=$3
14957         local name=$4
14958         local desc=$5
14959         local path=$DIR/$tdir/$name
14960         local fid
14961         local rc
14962         local fid_path
14963
14964         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
14965                 error "cannot create $desc"
14966
14967         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
14968         rc=$?
14969         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
14970
14971         fid_path=$($LFS fid2path $MOUNT $fid)
14972         rc=$?
14973         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
14974
14975         [ "$path" == "$fid_path" ] ||
14976                 error "fid2path returned $fid_path, expected $path"
14977
14978         echo "pass with $path and $fid"
14979 }
14980
14981 test_226a () {
14982         rm -rf $DIR/$tdir
14983         mkdir -p $DIR/$tdir
14984
14985         mcreate_path2fid 0010666 0 0 fifo "FIFO"
14986         mcreate_path2fid 0020666 1 3 null "character special file (null)"
14987         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
14988         mcreate_path2fid 0040666 0 0 dir "directory"
14989         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
14990         mcreate_path2fid 0100666 0 0 file "regular file"
14991         mcreate_path2fid 0120666 0 0 link "symbolic link"
14992         mcreate_path2fid 0140666 0 0 sock "socket"
14993 }
14994 run_test 226a "call path2fid and fid2path on files of all type"
14995
14996 test_226b () {
14997         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14998
14999         local MDTIDX=1
15000
15001         rm -rf $DIR/$tdir
15002         mkdir -p $DIR/$tdir
15003         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
15004                 error "create remote directory failed"
15005         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
15006         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
15007                                 "character special file (null)"
15008         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
15009                                 "character special file (no device)"
15010         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
15011         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
15012                                 "block special file (loop)"
15013         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
15014         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
15015         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
15016 }
15017 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
15018
15019 # LU-1299 Executing or running ldd on a truncated executable does not
15020 # cause an out-of-memory condition.
15021 test_227() {
15022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15023         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
15024
15025         dd if=$(which date) of=$MOUNT/date bs=1k count=1
15026         chmod +x $MOUNT/date
15027
15028         $MOUNT/date > /dev/null
15029         ldd $MOUNT/date > /dev/null
15030         rm -f $MOUNT/date
15031 }
15032 run_test 227 "running truncated executable does not cause OOM"
15033
15034 # LU-1512 try to reuse idle OI blocks
15035 test_228a() {
15036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15037         remote_mds_nodsh && skip "remote MDS with nodsh"
15038         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15039
15040         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15041         local myDIR=$DIR/$tdir
15042
15043         mkdir -p $myDIR
15044         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15045         $LCTL set_param fail_loc=0x80001002
15046         createmany -o $myDIR/t- 10000
15047         $LCTL set_param fail_loc=0
15048         # The guard is current the largest FID holder
15049         touch $myDIR/guard
15050         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15051                     tr -d '[')
15052         local IDX=$(($SEQ % 64))
15053
15054         do_facet $SINGLEMDS sync
15055         # Make sure journal flushed.
15056         sleep 6
15057         local blk1=$(do_facet $SINGLEMDS \
15058                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15059                      grep Blockcount | awk '{print $4}')
15060
15061         # Remove old files, some OI blocks will become idle.
15062         unlinkmany $myDIR/t- 10000
15063         # Create new files, idle OI blocks should be reused.
15064         createmany -o $myDIR/t- 2000
15065         do_facet $SINGLEMDS sync
15066         # Make sure journal flushed.
15067         sleep 6
15068         local blk2=$(do_facet $SINGLEMDS \
15069                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15070                      grep Blockcount | awk '{print $4}')
15071
15072         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15073 }
15074 run_test 228a "try to reuse idle OI blocks"
15075
15076 test_228b() {
15077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15078         remote_mds_nodsh && skip "remote MDS with nodsh"
15079         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15080
15081         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15082         local myDIR=$DIR/$tdir
15083
15084         mkdir -p $myDIR
15085         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15086         $LCTL set_param fail_loc=0x80001002
15087         createmany -o $myDIR/t- 10000
15088         $LCTL set_param fail_loc=0
15089         # The guard is current the largest FID holder
15090         touch $myDIR/guard
15091         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15092                     tr -d '[')
15093         local IDX=$(($SEQ % 64))
15094
15095         do_facet $SINGLEMDS sync
15096         # Make sure journal flushed.
15097         sleep 6
15098         local blk1=$(do_facet $SINGLEMDS \
15099                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15100                      grep Blockcount | awk '{print $4}')
15101
15102         # Remove old files, some OI blocks will become idle.
15103         unlinkmany $myDIR/t- 10000
15104
15105         # stop the MDT
15106         stop $SINGLEMDS || error "Fail to stop MDT."
15107         # remount the MDT
15108         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
15109
15110         df $MOUNT || error "Fail to df."
15111         # Create new files, idle OI blocks should be reused.
15112         createmany -o $myDIR/t- 2000
15113         do_facet $SINGLEMDS sync
15114         # Make sure journal flushed.
15115         sleep 6
15116         local blk2=$(do_facet $SINGLEMDS \
15117                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15118                      grep Blockcount | awk '{print $4}')
15119
15120         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15121 }
15122 run_test 228b "idle OI blocks can be reused after MDT restart"
15123
15124 #LU-1881
15125 test_228c() {
15126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15127         remote_mds_nodsh && skip "remote MDS with nodsh"
15128         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15129
15130         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15131         local myDIR=$DIR/$tdir
15132
15133         mkdir -p $myDIR
15134         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15135         $LCTL set_param fail_loc=0x80001002
15136         # 20000 files can guarantee there are index nodes in the OI file
15137         createmany -o $myDIR/t- 20000
15138         $LCTL set_param fail_loc=0
15139         # The guard is current the largest FID holder
15140         touch $myDIR/guard
15141         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15142                     tr -d '[')
15143         local IDX=$(($SEQ % 64))
15144
15145         do_facet $SINGLEMDS sync
15146         # Make sure journal flushed.
15147         sleep 6
15148         local blk1=$(do_facet $SINGLEMDS \
15149                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15150                      grep Blockcount | awk '{print $4}')
15151
15152         # Remove old files, some OI blocks will become idle.
15153         unlinkmany $myDIR/t- 20000
15154         rm -f $myDIR/guard
15155         # The OI file should become empty now
15156
15157         # Create new files, idle OI blocks should be reused.
15158         createmany -o $myDIR/t- 2000
15159         do_facet $SINGLEMDS sync
15160         # Make sure journal flushed.
15161         sleep 6
15162         local blk2=$(do_facet $SINGLEMDS \
15163                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15164                      grep Blockcount | awk '{print $4}')
15165
15166         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15167 }
15168 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
15169
15170 test_229() { # LU-2482, LU-3448
15171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15172         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
15173         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
15174                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
15175
15176         rm -f $DIR/$tfile
15177
15178         # Create a file with a released layout and stripe count 2.
15179         $MULTIOP $DIR/$tfile H2c ||
15180                 error "failed to create file with released layout"
15181
15182         $LFS getstripe -v $DIR/$tfile
15183
15184         local pattern=$($LFS getstripe -L $DIR/$tfile)
15185         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
15186
15187         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
15188                 error "getstripe"
15189         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
15190         stat $DIR/$tfile || error "failed to stat released file"
15191
15192         chown $RUNAS_ID $DIR/$tfile ||
15193                 error "chown $RUNAS_ID $DIR/$tfile failed"
15194
15195         chgrp $RUNAS_ID $DIR/$tfile ||
15196                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
15197
15198         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
15199         rm $DIR/$tfile || error "failed to remove released file"
15200 }
15201 run_test 229 "getstripe/stat/rm/attr changes work on released files"
15202
15203 test_230a() {
15204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15205         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15206         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15207                 skip "Need MDS version at least 2.11.52"
15208
15209         local MDTIDX=1
15210
15211         test_mkdir $DIR/$tdir
15212         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
15213         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
15214         [ $mdt_idx -ne 0 ] &&
15215                 error "create local directory on wrong MDT $mdt_idx"
15216
15217         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
15218                         error "create remote directory failed"
15219         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
15220         [ $mdt_idx -ne $MDTIDX ] &&
15221                 error "create remote directory on wrong MDT $mdt_idx"
15222
15223         createmany -o $DIR/$tdir/test_230/t- 10 ||
15224                 error "create files on remote directory failed"
15225         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
15226         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
15227         rm -r $DIR/$tdir || error "unlink remote directory failed"
15228 }
15229 run_test 230a "Create remote directory and files under the remote directory"
15230
15231 test_230b() {
15232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15233         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15234         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15235                 skip "Need MDS version at least 2.11.52"
15236
15237         local MDTIDX=1
15238         local mdt_index
15239         local i
15240         local file
15241         local pid
15242         local stripe_count
15243         local migrate_dir=$DIR/$tdir/migrate_dir
15244         local other_dir=$DIR/$tdir/other_dir
15245
15246         test_mkdir $DIR/$tdir
15247         test_mkdir -i0 -c1 $migrate_dir
15248         test_mkdir -i0 -c1 $other_dir
15249         for ((i=0; i<10; i++)); do
15250                 mkdir -p $migrate_dir/dir_${i}
15251                 createmany -o $migrate_dir/dir_${i}/f 10 ||
15252                         error "create files under remote dir failed $i"
15253         done
15254
15255         cp /etc/passwd $migrate_dir/$tfile
15256         cp /etc/passwd $other_dir/$tfile
15257         chattr +SAD $migrate_dir
15258         chattr +SAD $migrate_dir/$tfile
15259
15260         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15261         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15262         local old_dir_mode=$(stat -c%f $migrate_dir)
15263         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
15264
15265         mkdir -p $migrate_dir/dir_default_stripe2
15266         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
15267         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
15268
15269         mkdir -p $other_dir
15270         ln $migrate_dir/$tfile $other_dir/luna
15271         ln $migrate_dir/$tfile $migrate_dir/sofia
15272         ln $other_dir/$tfile $migrate_dir/david
15273         ln -s $migrate_dir/$tfile $other_dir/zachary
15274         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
15275         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
15276
15277         $LFS migrate -m $MDTIDX $migrate_dir ||
15278                 error "fails on migrating remote dir to MDT1"
15279
15280         echo "migratate to MDT1, then checking.."
15281         for ((i = 0; i < 10; i++)); do
15282                 for file in $(find $migrate_dir/dir_${i}); do
15283                         mdt_index=$($LFS getstripe -m $file)
15284                         [ $mdt_index == $MDTIDX ] ||
15285                                 error "$file is not on MDT${MDTIDX}"
15286                 done
15287         done
15288
15289         # the multiple link file should still in MDT0
15290         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
15291         [ $mdt_index == 0 ] ||
15292                 error "$file is not on MDT${MDTIDX}"
15293
15294         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15295         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15296                 error " expect $old_dir_flag get $new_dir_flag"
15297
15298         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15299         [ "$old_file_flag" = "$new_file_flag" ] ||
15300                 error " expect $old_file_flag get $new_file_flag"
15301
15302         local new_dir_mode=$(stat -c%f $migrate_dir)
15303         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15304                 error "expect mode $old_dir_mode get $new_dir_mode"
15305
15306         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15307         [ "$old_file_mode" = "$new_file_mode" ] ||
15308                 error "expect mode $old_file_mode get $new_file_mode"
15309
15310         diff /etc/passwd $migrate_dir/$tfile ||
15311                 error "$tfile different after migration"
15312
15313         diff /etc/passwd $other_dir/luna ||
15314                 error "luna different after migration"
15315
15316         diff /etc/passwd $migrate_dir/sofia ||
15317                 error "sofia different after migration"
15318
15319         diff /etc/passwd $migrate_dir/david ||
15320                 error "david different after migration"
15321
15322         diff /etc/passwd $other_dir/zachary ||
15323                 error "zachary different after migration"
15324
15325         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15326                 error "${tfile}_ln different after migration"
15327
15328         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15329                 error "${tfile}_ln_other different after migration"
15330
15331         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
15332         [ $stripe_count = 2 ] ||
15333                 error "dir strpe_count $d != 2 after migration."
15334
15335         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
15336         [ $stripe_count = 2 ] ||
15337                 error "file strpe_count $d != 2 after migration."
15338
15339         #migrate back to MDT0
15340         MDTIDX=0
15341
15342         $LFS migrate -m $MDTIDX $migrate_dir ||
15343                 error "fails on migrating remote dir to MDT0"
15344
15345         echo "migrate back to MDT0, checking.."
15346         for file in $(find $migrate_dir); do
15347                 mdt_index=$($LFS getstripe -m $file)
15348                 [ $mdt_index == $MDTIDX ] ||
15349                         error "$file is not on MDT${MDTIDX}"
15350         done
15351
15352         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15353         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15354                 error " expect $old_dir_flag get $new_dir_flag"
15355
15356         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15357         [ "$old_file_flag" = "$new_file_flag" ] ||
15358                 error " expect $old_file_flag get $new_file_flag"
15359
15360         local new_dir_mode=$(stat -c%f $migrate_dir)
15361         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15362                 error "expect mode $old_dir_mode get $new_dir_mode"
15363
15364         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15365         [ "$old_file_mode" = "$new_file_mode" ] ||
15366                 error "expect mode $old_file_mode get $new_file_mode"
15367
15368         diff /etc/passwd ${migrate_dir}/$tfile ||
15369                 error "$tfile different after migration"
15370
15371         diff /etc/passwd ${other_dir}/luna ||
15372                 error "luna different after migration"
15373
15374         diff /etc/passwd ${migrate_dir}/sofia ||
15375                 error "sofia different after migration"
15376
15377         diff /etc/passwd ${other_dir}/zachary ||
15378                 error "zachary different after migration"
15379
15380         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15381                 error "${tfile}_ln different after migration"
15382
15383         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15384                 error "${tfile}_ln_other different after migration"
15385
15386         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
15387         [ $stripe_count = 2 ] ||
15388                 error "dir strpe_count $d != 2 after migration."
15389
15390         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
15391         [ $stripe_count = 2 ] ||
15392                 error "file strpe_count $d != 2 after migration."
15393
15394         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15395 }
15396 run_test 230b "migrate directory"
15397
15398 test_230c() {
15399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15400         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15401         remote_mds_nodsh && skip "remote MDS with nodsh"
15402         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15403                 skip "Need MDS version at least 2.11.52"
15404
15405         local MDTIDX=1
15406         local total=3
15407         local mdt_index
15408         local file
15409         local migrate_dir=$DIR/$tdir/migrate_dir
15410
15411         #If migrating directory fails in the middle, all entries of
15412         #the directory is still accessiable.
15413         test_mkdir $DIR/$tdir
15414         test_mkdir -i0 -c1 $migrate_dir
15415         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
15416         stat $migrate_dir
15417         createmany -o $migrate_dir/f $total ||
15418                 error "create files under ${migrate_dir} failed"
15419
15420         # fail after migrating top dir, and this will fail only once, so the
15421         # first sub file migration will fail (currently f3), others succeed.
15422         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
15423         do_facet mds1 lctl set_param fail_loc=0x1801
15424         local t=$(ls $migrate_dir | wc -l)
15425         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
15426                 error "migrate should fail"
15427         local u=$(ls $migrate_dir | wc -l)
15428         [ "$u" == "$t" ] || error "$u != $t during migration"
15429
15430         # add new dir/file should succeed
15431         mkdir $migrate_dir/dir ||
15432                 error "mkdir failed under migrating directory"
15433         touch $migrate_dir/file ||
15434                 error "create file failed under migrating directory"
15435
15436         # add file with existing name should fail
15437         for file in $migrate_dir/f*; do
15438                 stat $file > /dev/null || error "stat $file failed"
15439                 $OPENFILE -f O_CREAT:O_EXCL $file &&
15440                         error "open(O_CREAT|O_EXCL) $file should fail"
15441                 $MULTIOP $file m && error "create $file should fail"
15442                 touch $DIR/$tdir/remote_dir/$tfile ||
15443                         error "touch $tfile failed"
15444                 ln $DIR/$tdir/remote_dir/$tfile $file &&
15445                         error "link $file should fail"
15446                 mdt_index=$($LFS getstripe -m $file)
15447                 if [ $mdt_index == 0 ]; then
15448                         # file failed to migrate is not allowed to rename to
15449                         mv $DIR/$tdir/remote_dir/$tfile $file &&
15450                                 error "rename to $file should fail"
15451                 else
15452                         mv $DIR/$tdir/remote_dir/$tfile $file ||
15453                                 error "rename to $file failed"
15454                 fi
15455                 echo hello >> $file || error "write $file failed"
15456         done
15457
15458         # resume migration with different options should fail
15459         $LFS migrate -m 0 $migrate_dir &&
15460                 error "migrate -m 0 $migrate_dir should fail"
15461
15462         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
15463                 error "migrate -c 2 $migrate_dir should fail"
15464
15465         # resume migration should succeed
15466         $LFS migrate -m $MDTIDX $migrate_dir ||
15467                 error "migrate $migrate_dir failed"
15468
15469         echo "Finish migration, then checking.."
15470         for file in $(find $migrate_dir); do
15471                 mdt_index=$($LFS getstripe -m $file)
15472                 [ $mdt_index == $MDTIDX ] ||
15473                         error "$file is not on MDT${MDTIDX}"
15474         done
15475
15476         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15477 }
15478 run_test 230c "check directory accessiblity if migration failed"
15479
15480 test_230d() {
15481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15482         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15483         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15484                 skip "Need MDS version at least 2.11.52"
15485         # LU-11235
15486         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
15487
15488         local migrate_dir=$DIR/$tdir/migrate_dir
15489         local old_index
15490         local new_index
15491         local old_count
15492         local new_count
15493         local new_hash
15494         local mdt_index
15495         local i
15496         local j
15497
15498         old_index=$((RANDOM % MDSCOUNT))
15499         old_count=$((MDSCOUNT - old_index))
15500         new_index=$((RANDOM % MDSCOUNT))
15501         new_count=$((MDSCOUNT - new_index))
15502         new_hash="all_char"
15503
15504         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
15505         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
15506
15507         test_mkdir $DIR/$tdir
15508         test_mkdir -i $old_index -c $old_count $migrate_dir
15509
15510         for ((i=0; i<100; i++)); do
15511                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
15512                 createmany -o $migrate_dir/dir_${i}/f 100 ||
15513                         error "create files under remote dir failed $i"
15514         done
15515
15516         echo -n "Migrate from MDT$old_index "
15517         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
15518         echo -n "to MDT$new_index"
15519         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
15520         echo
15521
15522         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
15523         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
15524                 error "migrate remote dir error"
15525
15526         echo "Finish migration, then checking.."
15527         for file in $(find $migrate_dir); do
15528                 mdt_index=$($LFS getstripe -m $file)
15529                 if [ $mdt_index -lt $new_index ] ||
15530                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
15531                         error "$file is on MDT$mdt_index"
15532                 fi
15533         done
15534
15535         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15536 }
15537 run_test 230d "check migrate big directory"
15538
15539 test_230e() {
15540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15541         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15542         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15543                 skip "Need MDS version at least 2.11.52"
15544
15545         local i
15546         local j
15547         local a_fid
15548         local b_fid
15549
15550         mkdir -p $DIR/$tdir
15551         mkdir $DIR/$tdir/migrate_dir
15552         mkdir $DIR/$tdir/other_dir
15553         touch $DIR/$tdir/migrate_dir/a
15554         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
15555         ls $DIR/$tdir/other_dir
15556
15557         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15558                 error "migrate dir fails"
15559
15560         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
15561         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
15562
15563         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15564         [ $mdt_index == 0 ] || error "a is not on MDT0"
15565
15566         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
15567                 error "migrate dir fails"
15568
15569         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
15570         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
15571
15572         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15573         [ $mdt_index == 1 ] || error "a is not on MDT1"
15574
15575         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
15576         [ $mdt_index == 1 ] || error "b is not on MDT1"
15577
15578         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
15579         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
15580
15581         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
15582
15583         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15584 }
15585 run_test 230e "migrate mulitple local link files"
15586
15587 test_230f() {
15588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15589         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15590         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15591                 skip "Need MDS version at least 2.11.52"
15592
15593         local a_fid
15594         local ln_fid
15595
15596         mkdir -p $DIR/$tdir
15597         mkdir $DIR/$tdir/migrate_dir
15598         $LFS mkdir -i1 $DIR/$tdir/other_dir
15599         touch $DIR/$tdir/migrate_dir/a
15600         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
15601         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
15602         ls $DIR/$tdir/other_dir
15603
15604         # a should be migrated to MDT1, since no other links on MDT0
15605         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15606                 error "#1 migrate dir fails"
15607         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
15608         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
15609         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15610         [ $mdt_index == 1 ] || error "a is not on MDT1"
15611
15612         # a should stay on MDT1, because it is a mulitple link file
15613         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
15614                 error "#2 migrate dir fails"
15615         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15616         [ $mdt_index == 1 ] || error "a is not on MDT1"
15617
15618         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15619                 error "#3 migrate dir fails"
15620
15621         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
15622         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
15623         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
15624
15625         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
15626         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
15627
15628         # a should be migrated to MDT0, since no other links on MDT1
15629         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
15630                 error "#4 migrate dir fails"
15631         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15632         [ $mdt_index == 0 ] || error "a is not on MDT0"
15633
15634         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15635 }
15636 run_test 230f "migrate mulitple remote link files"
15637
15638 test_230g() {
15639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15640         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15641         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15642                 skip "Need MDS version at least 2.11.52"
15643
15644         mkdir -p $DIR/$tdir/migrate_dir
15645
15646         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
15647                 error "migrating dir to non-exist MDT succeeds"
15648         true
15649 }
15650 run_test 230g "migrate dir to non-exist MDT"
15651
15652 test_230h() {
15653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15654         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15655         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15656                 skip "Need MDS version at least 2.11.52"
15657
15658         local mdt_index
15659
15660         mkdir -p $DIR/$tdir/migrate_dir
15661
15662         $LFS migrate -m1 $DIR &&
15663                 error "migrating mountpoint1 should fail"
15664
15665         $LFS migrate -m1 $DIR/$tdir/.. &&
15666                 error "migrating mountpoint2 should fail"
15667
15668         # same as mv
15669         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
15670                 error "migrating $tdir/migrate_dir/.. should fail"
15671
15672         true
15673 }
15674 run_test 230h "migrate .. and root"
15675
15676 test_230i() {
15677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15678         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15679         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15680                 skip "Need MDS version at least 2.11.52"
15681
15682         mkdir -p $DIR/$tdir/migrate_dir
15683
15684         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
15685                 error "migration fails with a tailing slash"
15686
15687         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
15688                 error "migration fails with two tailing slashes"
15689 }
15690 run_test 230i "lfs migrate -m tolerates trailing slashes"
15691
15692 test_230j() {
15693         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
15694         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15695                 skip "Need MDS version at least 2.11.52"
15696
15697         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
15698         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
15699                 error "create $tfile failed"
15700         cat /etc/passwd > $DIR/$tdir/$tfile
15701
15702         $LFS migrate -m 1 $DIR/$tdir
15703
15704         cmp /etc/passwd $DIR/$tdir/$tfile ||
15705                 error "DoM file mismatch after migration"
15706 }
15707 run_test 230j "DoM file data not changed after dir migration"
15708
15709 test_230k() {
15710         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
15711         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
15712                 skip "Need MDS version at least 2.11.56"
15713
15714         local total=20
15715         local files_on_starting_mdt=0
15716
15717         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
15718         $LFS getdirstripe $DIR/$tdir
15719         for i in $(seq $total); do
15720                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
15721                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
15722                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15723         done
15724
15725         echo "$files_on_starting_mdt files on MDT0"
15726
15727         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
15728         $LFS getdirstripe $DIR/$tdir
15729
15730         files_on_starting_mdt=0
15731         for i in $(seq $total); do
15732                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
15733                         error "file $tfile.$i mismatch after migration"
15734                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
15735                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15736         done
15737
15738         echo "$files_on_starting_mdt files on MDT1 after migration"
15739         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
15740
15741         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
15742         $LFS getdirstripe $DIR/$tdir
15743
15744         files_on_starting_mdt=0
15745         for i in $(seq $total); do
15746                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
15747                         error "file $tfile.$i mismatch after 2nd migration"
15748                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
15749                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15750         done
15751
15752         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
15753         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
15754
15755         true
15756 }
15757 run_test 230k "file data not changed after dir migration"
15758
15759 test_230l() {
15760         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
15761         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
15762                 skip "Need MDS version at least 2.11.56"
15763
15764         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
15765         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
15766                 error "create files under remote dir failed $i"
15767         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
15768 }
15769 run_test 230l "readdir between MDTs won't crash"
15770
15771 test_231a()
15772 {
15773         # For simplicity this test assumes that max_pages_per_rpc
15774         # is the same across all OSCs
15775         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
15776         local bulk_size=$((max_pages * PAGE_SIZE))
15777         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
15778                                        head -n 1)
15779
15780         mkdir -p $DIR/$tdir
15781         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
15782                 error "failed to set stripe with -S ${brw_size}M option"
15783
15784         # clear the OSC stats
15785         $LCTL set_param osc.*.stats=0 &>/dev/null
15786         stop_writeback
15787
15788         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
15789         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
15790                 oflag=direct &>/dev/null || error "dd failed"
15791
15792         sync; sleep 1; sync # just to be safe
15793         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
15794         if [ x$nrpcs != "x1" ]; then
15795                 $LCTL get_param osc.*.stats
15796                 error "found $nrpcs ost_write RPCs, not 1 as expected"
15797         fi
15798
15799         start_writeback
15800         # Drop the OSC cache, otherwise we will read from it
15801         cancel_lru_locks osc
15802
15803         # clear the OSC stats
15804         $LCTL set_param osc.*.stats=0 &>/dev/null
15805
15806         # Client reads $bulk_size.
15807         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
15808                 iflag=direct &>/dev/null || error "dd failed"
15809
15810         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
15811         if [ x$nrpcs != "x1" ]; then
15812                 $LCTL get_param osc.*.stats
15813                 error "found $nrpcs ost_read RPCs, not 1 as expected"
15814         fi
15815 }
15816 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
15817
15818 test_231b() {
15819         mkdir -p $DIR/$tdir
15820         local i
15821         for i in {0..1023}; do
15822                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
15823                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
15824                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
15825         done
15826         sync
15827 }
15828 run_test 231b "must not assert on fully utilized OST request buffer"
15829
15830 test_232a() {
15831         mkdir -p $DIR/$tdir
15832         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
15833
15834         #define OBD_FAIL_LDLM_OST_LVB            0x31c
15835         do_facet ost1 $LCTL set_param fail_loc=0x31c
15836
15837         # ignore dd failure
15838         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
15839
15840         do_facet ost1 $LCTL set_param fail_loc=0
15841         umount_client $MOUNT || error "umount failed"
15842         mount_client $MOUNT || error "mount failed"
15843         stop ost1 || error "cannot stop ost1"
15844         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
15845 }
15846 run_test 232a "failed lock should not block umount"
15847
15848 test_232b() {
15849         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
15850                 skip "Need MDS version at least 2.10.58"
15851
15852         mkdir -p $DIR/$tdir
15853         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
15854         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
15855         sync
15856         cancel_lru_locks osc
15857
15858         #define OBD_FAIL_LDLM_OST_LVB            0x31c
15859         do_facet ost1 $LCTL set_param fail_loc=0x31c
15860
15861         # ignore failure
15862         $LFS data_version $DIR/$tdir/$tfile || true
15863
15864         do_facet ost1 $LCTL set_param fail_loc=0
15865         umount_client $MOUNT || error "umount failed"
15866         mount_client $MOUNT || error "mount failed"
15867         stop ost1 || error "cannot stop ost1"
15868         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
15869 }
15870 run_test 232b "failed data version lock should not block umount"
15871
15872 test_233a() {
15873         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
15874                 skip "Need MDS version at least 2.3.64"
15875         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
15876
15877         local fid=$($LFS path2fid $MOUNT)
15878
15879         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15880                 error "cannot access $MOUNT using its FID '$fid'"
15881 }
15882 run_test 233a "checking that OBF of the FS root succeeds"
15883
15884 test_233b() {
15885         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
15886                 skip "Need MDS version at least 2.5.90"
15887         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
15888
15889         local fid=$($LFS path2fid $MOUNT/.lustre)
15890
15891         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15892                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
15893
15894         fid=$($LFS path2fid $MOUNT/.lustre/fid)
15895         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15896                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
15897 }
15898 run_test 233b "checking that OBF of the FS .lustre succeeds"
15899
15900 test_234() {
15901         local p="$TMP/sanityN-$TESTNAME.parameters"
15902         save_lustre_params client "llite.*.xattr_cache" > $p
15903         lctl set_param llite.*.xattr_cache 1 ||
15904                 skip_env "xattr cache is not supported"
15905
15906         mkdir -p $DIR/$tdir || error "mkdir failed"
15907         touch $DIR/$tdir/$tfile || error "touch failed"
15908         # OBD_FAIL_LLITE_XATTR_ENOMEM
15909         $LCTL set_param fail_loc=0x1405
15910         getfattr -n user.attr $DIR/$tdir/$tfile &&
15911                 error "getfattr should have failed with ENOMEM"
15912         $LCTL set_param fail_loc=0x0
15913         rm -rf $DIR/$tdir
15914
15915         restore_lustre_params < $p
15916         rm -f $p
15917 }
15918 run_test 234 "xattr cache should not crash on ENOMEM"
15919
15920 test_235() {
15921         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
15922                 skip "Need MDS version at least 2.4.52"
15923
15924         flock_deadlock $DIR/$tfile
15925         local RC=$?
15926         case $RC in
15927                 0)
15928                 ;;
15929                 124) error "process hangs on a deadlock"
15930                 ;;
15931                 *) error "error executing flock_deadlock $DIR/$tfile"
15932                 ;;
15933         esac
15934 }
15935 run_test 235 "LU-1715: flock deadlock detection does not work properly"
15936
15937 #LU-2935
15938 test_236() {
15939         check_swap_layouts_support
15940
15941         local ref1=/etc/passwd
15942         local ref2=/etc/group
15943         local file1=$DIR/$tdir/f1
15944         local file2=$DIR/$tdir/f2
15945
15946         test_mkdir -c1 $DIR/$tdir
15947         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
15948         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
15949         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
15950         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
15951         local fd=$(free_fd)
15952         local cmd="exec $fd<>$file2"
15953         eval $cmd
15954         rm $file2
15955         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
15956                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
15957         cmd="exec $fd>&-"
15958         eval $cmd
15959         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
15960
15961         #cleanup
15962         rm -rf $DIR/$tdir
15963 }
15964 run_test 236 "Layout swap on open unlinked file"
15965
15966 # LU-4659 linkea consistency
15967 test_238() {
15968         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15969                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15970                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15971                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15972
15973         touch $DIR/$tfile
15974         ln $DIR/$tfile $DIR/$tfile.lnk
15975         touch $DIR/$tfile.new
15976         mv $DIR/$tfile.new $DIR/$tfile
15977         local fid1=$($LFS path2fid $DIR/$tfile)
15978         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
15979         local path1=$($LFS fid2path $FSNAME "$fid1")
15980         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
15981         local path2=$($LFS fid2path $FSNAME "$fid2")
15982         [ $tfile.lnk == $path2 ] ||
15983                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
15984         rm -f $DIR/$tfile*
15985 }
15986 run_test 238 "Verify linkea consistency"
15987
15988 test_239A() { # was test_239
15989         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
15990                 skip "Need MDS version at least 2.5.60"
15991
15992         local list=$(comma_list $(mdts_nodes))
15993
15994         mkdir -p $DIR/$tdir
15995         createmany -o $DIR/$tdir/f- 5000
15996         unlinkmany $DIR/$tdir/f- 5000
15997         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
15998                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
15999         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
16000                         osp.*MDT*.sync_in_flight" | calc_sum)
16001         [ "$changes" -eq 0 ] || error "$changes not synced"
16002 }
16003 run_test 239A "osp_sync test"
16004
16005 test_239a() { #LU-5297
16006         remote_mds_nodsh && skip "remote MDS with nodsh"
16007
16008         touch $DIR/$tfile
16009         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
16010         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
16011         chgrp $RUNAS_GID $DIR/$tfile
16012         wait_delete_completed
16013 }
16014 run_test 239a "process invalid osp sync record correctly"
16015
16016 test_239b() { #LU-5297
16017         remote_mds_nodsh && skip "remote MDS with nodsh"
16018
16019         touch $DIR/$tfile1
16020         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
16021         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
16022         chgrp $RUNAS_GID $DIR/$tfile1
16023         wait_delete_completed
16024         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16025         touch $DIR/$tfile2
16026         chgrp $RUNAS_GID $DIR/$tfile2
16027         wait_delete_completed
16028 }
16029 run_test 239b "process osp sync record with ENOMEM error correctly"
16030
16031 test_240() {
16032         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16033         remote_mds_nodsh && skip "remote MDS with nodsh"
16034
16035         mkdir -p $DIR/$tdir
16036
16037         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
16038                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
16039         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
16040                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
16041
16042         umount_client $MOUNT || error "umount failed"
16043         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
16044         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
16045         mount_client $MOUNT || error "failed to mount client"
16046
16047         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
16048         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
16049 }
16050 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
16051
16052 test_241_bio() {
16053         local count=$1
16054         local bsize=$2
16055
16056         for LOOP in $(seq $count); do
16057                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
16058                 cancel_lru_locks $OSC || true
16059         done
16060 }
16061
16062 test_241_dio() {
16063         local count=$1
16064         local bsize=$2
16065
16066         for LOOP in $(seq $1); do
16067                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
16068                         2>/dev/null
16069         done
16070 }
16071
16072 test_241a() { # was test_241
16073         local bsize=$PAGE_SIZE
16074
16075         (( bsize < 40960 )) && bsize=40960
16076         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16077         ls -la $DIR/$tfile
16078         cancel_lru_locks $OSC
16079         test_241_bio 1000 $bsize &
16080         PID=$!
16081         test_241_dio 1000 $bsize
16082         wait $PID
16083 }
16084 run_test 241a "bio vs dio"
16085
16086 test_241b() {
16087         local bsize=$PAGE_SIZE
16088
16089         (( bsize < 40960 )) && bsize=40960
16090         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16091         ls -la $DIR/$tfile
16092         test_241_dio 1000 $bsize &
16093         PID=$!
16094         test_241_dio 1000 $bsize
16095         wait $PID
16096 }
16097 run_test 241b "dio vs dio"
16098
16099 test_242() {
16100         remote_mds_nodsh && skip "remote MDS with nodsh"
16101
16102         mkdir -p $DIR/$tdir
16103         touch $DIR/$tdir/$tfile
16104
16105         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
16106         do_facet mds1 lctl set_param fail_loc=0x105
16107         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
16108
16109         do_facet mds1 lctl set_param fail_loc=0
16110         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
16111 }
16112 run_test 242 "mdt_readpage failure should not cause directory unreadable"
16113
16114 test_243()
16115 {
16116         test_mkdir $DIR/$tdir
16117         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
16118 }
16119 run_test 243 "various group lock tests"
16120
16121 test_244()
16122 {
16123         test_mkdir $DIR/$tdir
16124         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
16125         sendfile_grouplock $DIR/$tdir/$tfile || \
16126                 error "sendfile+grouplock failed"
16127         rm -rf $DIR/$tdir
16128 }
16129 run_test 244 "sendfile with group lock tests"
16130
16131 test_245() {
16132         local flagname="multi_mod_rpcs"
16133         local connect_data_name="max_mod_rpcs"
16134         local out
16135
16136         # check if multiple modify RPCs flag is set
16137         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
16138                 grep "connect_flags:")
16139         echo "$out"
16140
16141         echo "$out" | grep -qw $flagname
16142         if [ $? -ne 0 ]; then
16143                 echo "connect flag $flagname is not set"
16144                 return
16145         fi
16146
16147         # check if multiple modify RPCs data is set
16148         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
16149         echo "$out"
16150
16151         echo "$out" | grep -qw $connect_data_name ||
16152                 error "import should have connect data $connect_data_name"
16153 }
16154 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
16155
16156 test_246() { # LU-7371
16157         remote_ost_nodsh && skip "remote OST with nodsh"
16158         [ $OST1_VERSION -lt $(version_code 2.7.62) ] &&
16159                 skip "Need OST version >= 2.7.62"
16160
16161         do_facet ost1 $LCTL set_param fail_val=4095
16162 #define OBD_FAIL_OST_READ_SIZE          0x234
16163         do_facet ost1 $LCTL set_param fail_loc=0x234
16164         $LFS setstripe $DIR/$tfile -i 0 -c 1
16165         dd if=/dev/zero of=$DIR/$tfile bs=4095 count=1 > /dev/null 2>&1
16166         cancel_lru_locks $FSNAME-OST0000
16167         dd if=$DIR/$tfile of=/dev/null bs=1048576 || error "Read failed"
16168 }
16169 run_test 246 "Read file of size 4095 should return right length"
16170
16171 cleanup_247() {
16172         local submount=$1
16173
16174         trap 0
16175         umount_client $submount
16176         rmdir $submount
16177 }
16178
16179 test_247a() {
16180         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16181                 grep -q subtree ||
16182                 skip_env "Fileset feature is not supported"
16183
16184         local submount=${MOUNT}_$tdir
16185
16186         mkdir $MOUNT/$tdir
16187         mkdir -p $submount || error "mkdir $submount failed"
16188         FILESET="$FILESET/$tdir" mount_client $submount ||
16189                 error "mount $submount failed"
16190         trap "cleanup_247 $submount" EXIT
16191         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
16192         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
16193                 error "read $MOUNT/$tdir/$tfile failed"
16194         cleanup_247 $submount
16195 }
16196 run_test 247a "mount subdir as fileset"
16197
16198 test_247b() {
16199         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16200                 skip_env "Fileset feature is not supported"
16201
16202         local submount=${MOUNT}_$tdir
16203
16204         rm -rf $MOUNT/$tdir
16205         mkdir -p $submount || error "mkdir $submount failed"
16206         SKIP_FILESET=1
16207         FILESET="$FILESET/$tdir" mount_client $submount &&
16208                 error "mount $submount should fail"
16209         rmdir $submount
16210 }
16211 run_test 247b "mount subdir that dose not exist"
16212
16213 test_247c() {
16214         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16215                 skip_env "Fileset feature is not supported"
16216
16217         local submount=${MOUNT}_$tdir
16218
16219         mkdir -p $MOUNT/$tdir/dir1
16220         mkdir -p $submount || error "mkdir $submount failed"
16221         trap "cleanup_247 $submount" EXIT
16222         FILESET="$FILESET/$tdir" mount_client $submount ||
16223                 error "mount $submount failed"
16224         local fid=$($LFS path2fid $MOUNT/)
16225         $LFS fid2path $submount $fid && error "fid2path should fail"
16226         cleanup_247 $submount
16227 }
16228 run_test 247c "running fid2path outside root"
16229
16230 test_247d() {
16231         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16232                 skip "Fileset feature is not supported"
16233
16234         local submount=${MOUNT}_$tdir
16235
16236         mkdir -p $MOUNT/$tdir/dir1
16237         mkdir -p $submount || error "mkdir $submount failed"
16238         FILESET="$FILESET/$tdir" mount_client $submount ||
16239                 error "mount $submount failed"
16240         trap "cleanup_247 $submount" EXIT
16241         local fid=$($LFS path2fid $submount/dir1)
16242         $LFS fid2path $submount $fid || error "fid2path should succeed"
16243         cleanup_247 $submount
16244 }
16245 run_test 247d "running fid2path inside root"
16246
16247 # LU-8037
16248 test_247e() {
16249         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16250                 grep -q subtree ||
16251                 skip "Fileset feature is not supported"
16252
16253         local submount=${MOUNT}_$tdir
16254
16255         mkdir $MOUNT/$tdir
16256         mkdir -p $submount || error "mkdir $submount failed"
16257         FILESET="$FILESET/.." mount_client $submount &&
16258                 error "mount $submount should fail"
16259         rmdir $submount
16260 }
16261 run_test 247e "mount .. as fileset"
16262
16263 test_248() {
16264         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
16265         [ -z "$fast_read_sav" ] && skip "no fast read support"
16266
16267         # create a large file for fast read verification
16268         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
16269
16270         # make sure the file is created correctly
16271         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
16272                 { rm -f $DIR/$tfile; skip "file creation error"; }
16273
16274         echo "Test 1: verify that fast read is 4 times faster on cache read"
16275
16276         # small read with fast read enabled
16277         $LCTL set_param -n llite.*.fast_read=1
16278         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16279                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16280                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16281         # small read with fast read disabled
16282         $LCTL set_param -n llite.*.fast_read=0
16283         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16284                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16285                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16286
16287         # verify that fast read is 4 times faster for cache read
16288         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
16289                 error_not_in_vm "fast read was not 4 times faster: " \
16290                            "$t_fast vs $t_slow"
16291
16292         echo "Test 2: verify the performance between big and small read"
16293         $LCTL set_param -n llite.*.fast_read=1
16294
16295         # 1k non-cache read
16296         cancel_lru_locks osc
16297         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16298                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16299                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16300
16301         # 1M non-cache read
16302         cancel_lru_locks osc
16303         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16304                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16305                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16306
16307         # verify that big IO is not 4 times faster than small IO
16308         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
16309                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
16310
16311         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
16312         rm -f $DIR/$tfile
16313 }
16314 run_test 248 "fast read verification"
16315
16316 test_249() { # LU-7890
16317         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
16318                 skip "Need at least version 2.8.54"
16319
16320         rm -f $DIR/$tfile
16321         $LFS setstripe -c 1 $DIR/$tfile
16322         # Offset 2T == 4k * 512M
16323         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
16324                 error "dd to 2T offset failed"
16325 }
16326 run_test 249 "Write above 2T file size"
16327
16328 test_250() {
16329         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
16330          && skip "no 16TB file size limit on ZFS"
16331
16332         $LFS setstripe -c 1 $DIR/$tfile
16333         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
16334         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
16335         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
16336         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
16337                 conv=notrunc,fsync && error "append succeeded"
16338         return 0
16339 }
16340 run_test 250 "Write above 16T limit"
16341
16342 test_251() {
16343         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
16344
16345         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
16346         #Skip once - writing the first stripe will succeed
16347         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16348         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
16349                 error "short write happened"
16350
16351         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16352         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
16353                 error "short read happened"
16354
16355         rm -f $DIR/$tfile
16356 }
16357 run_test 251 "Handling short read and write correctly"
16358
16359 test_252() {
16360         remote_mds_nodsh && skip "remote MDS with nodsh"
16361         remote_ost_nodsh && skip "remote OST with nodsh"
16362         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
16363                 skip_env "ldiskfs only test"
16364         fi
16365
16366         local tgt
16367         local dev
16368         local out
16369         local uuid
16370         local num
16371         local gen
16372
16373         # check lr_reader on OST0000
16374         tgt=ost1
16375         dev=$(facet_device $tgt)
16376         out=$(do_facet $tgt $LR_READER $dev)
16377         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16378         echo "$out"
16379         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
16380         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
16381                 error "Invalid uuid returned by $LR_READER on target $tgt"
16382         echo -e "uuid returned by $LR_READER is '$uuid'\n"
16383
16384         # check lr_reader -c on MDT0000
16385         tgt=mds1
16386         dev=$(facet_device $tgt)
16387         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
16388                 skip "$LR_READER does not support additional options"
16389         fi
16390         out=$(do_facet $tgt $LR_READER -c $dev)
16391         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16392         echo "$out"
16393         num=$(echo "$out" | grep -c "mdtlov")
16394         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
16395                 error "Invalid number of mdtlov clients returned by $LR_READER"
16396         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
16397
16398         # check lr_reader -cr on MDT0000
16399         out=$(do_facet $tgt $LR_READER -cr $dev)
16400         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16401         echo "$out"
16402         echo "$out" | grep -q "^reply_data:$" ||
16403                 error "$LR_READER should have returned 'reply_data' section"
16404         num=$(echo "$out" | grep -c "client_generation")
16405         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
16406 }
16407 run_test 252 "check lr_reader tool"
16408
16409 test_253_fill_ost() {
16410         local size_mb #how many MB should we write to pass watermark
16411         local lwm=$3  #low watermark
16412         local free_10mb #10% of free space
16413
16414         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16415         size_mb=$((free_kb / 1024 - lwm))
16416         free_10mb=$((free_kb / 10240))
16417         #If 10% of free space cross low watermark use it
16418         if (( free_10mb > size_mb )); then
16419                 size_mb=$free_10mb
16420         else
16421                 #At least we need to store 1.1 of difference between
16422                 #free space and low watermark
16423                 size_mb=$((size_mb + size_mb / 10))
16424         fi
16425         if (( lwm <= $((free_kb / 1024)) )) || [ ! -f $DIR/$tdir/1 ]; then
16426                 dd if=/dev/zero of=$DIR/$tdir/1 bs=1M count=$size_mb \
16427                          oflag=append conv=notrunc
16428         fi
16429
16430         sleep_maxage
16431
16432         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16433         echo "OST still has $((free_kb / 1024)) mbytes free"
16434 }
16435
16436 test_253() {
16437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16438         remote_mds_nodsh && skip "remote MDS with nodsh"
16439         remote_mgs_nodsh && skip "remote MGS with nodsh"
16440
16441         local ostidx=0
16442         local rc=0
16443
16444         local ost_name=$($LFS osts |
16445                 sed -n 's/^'$ostidx': \(.*\)_UUID .*/\1/p')
16446         # on the mdt's osc
16447         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
16448         do_facet $SINGLEMDS $LCTL get_param -n \
16449                 osp.$mdtosc_proc1.reserved_mb_high ||
16450                 skip  "remote MDS does not support reserved_mb_high"
16451
16452         rm -rf $DIR/$tdir
16453         wait_mds_ost_sync
16454         wait_delete_completed
16455         mkdir $DIR/$tdir
16456
16457         local last_wm_h=$(do_facet $SINGLEMDS $LCTL get_param -n \
16458                         osp.$mdtosc_proc1.reserved_mb_high)
16459         local last_wm_l=$(do_facet $SINGLEMDS $LCTL get_param -n \
16460                         osp.$mdtosc_proc1.reserved_mb_low)
16461         echo "prev high watermark $last_wm_h, prev low watermark $last_wm_l"
16462
16463         if ! combined_mgs_mds ; then
16464                 mount_mgs_client
16465         fi
16466         create_pool $FSNAME.$TESTNAME || error "Pool creation failed"
16467         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $ost_name ||
16468                 error "Adding $ost_name to pool failed"
16469
16470         # Wait for client to see a OST at pool
16471         wait_update $HOSTNAME "$LCTL get_param -n
16472                 lov.$FSNAME-*.pools.$TESTNAME | sort -u |
16473                 grep $ost_name" "$ost_name""_UUID" $((TIMEOUT/2)) ||
16474                 error "Client can not see the pool"
16475         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
16476                 error "Setstripe failed"
16477
16478         dd if=/dev/zero of=$DIR/$tdir/0 bs=1M count=10
16479         local blocks=$($LFS df $MOUNT | grep $ost_name | awk '{ print $4 }')
16480         echo "OST still has $((blocks/1024)) mbytes free"
16481
16482         local new_lwm=$((blocks/1024-10))
16483         do_facet $SINGLEMDS $LCTL set_param \
16484                         osp.$mdtosc_proc1.reserved_mb_high=$((new_lwm+5))
16485         do_facet $SINGLEMDS $LCTL set_param \
16486                         osp.$mdtosc_proc1.reserved_mb_low=$new_lwm
16487
16488         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16489
16490         #First enospc could execute orphan deletion so repeat.
16491         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16492
16493         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16494                         osp.$mdtosc_proc1.prealloc_status)
16495         echo "prealloc_status $oa_status"
16496
16497         dd if=/dev/zero of=$DIR/$tdir/2 bs=1M count=1 &&
16498                 error "File creation should fail"
16499         #object allocation was stopped, but we still able to append files
16500         dd if=/dev/zero of=$DIR/$tdir/1 bs=1M seek=6 count=5 oflag=append ||
16501                 error "Append failed"
16502         rm -f $DIR/$tdir/1 $DIR/$tdir/0 $DIR/$tdir/r*
16503
16504         wait_delete_completed
16505
16506         sleep_maxage
16507
16508         for i in $(seq 10 12); do
16509                 dd if=/dev/zero of=$DIR/$tdir/$i bs=1M count=1 2>/dev/null ||
16510                         error "File creation failed after rm";
16511         done
16512
16513         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16514                         osp.$mdtosc_proc1.prealloc_status)
16515         echo "prealloc_status $oa_status"
16516
16517         if (( oa_status != 0 )); then
16518                 error "Object allocation still disable after rm"
16519         fi
16520         do_facet $SINGLEMDS $LCTL set_param \
16521                         osp.$mdtosc_proc1.reserved_mb_high=$last_wm_h
16522         do_facet $SINGLEMDS $LCTL set_param \
16523                         osp.$mdtosc_proc1.reserved_mb_low=$last_wm_l
16524
16525
16526         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $ost_name ||
16527                 error "Remove $ost_name from pool failed"
16528         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
16529                 error "Pool destroy fialed"
16530
16531         if ! combined_mgs_mds ; then
16532                 umount_mgs_client
16533         fi
16534 }
16535 run_test 253 "Check object allocation limit"
16536
16537 test_254() {
16538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16539         remote_mds_nodsh && skip "remote MDS with nodsh"
16540         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
16541                 skip "MDS does not support changelog_size"
16542
16543         local cl_user
16544         local MDT0=$(facet_svc $SINGLEMDS)
16545
16546         changelog_register || error "changelog_register failed"
16547
16548         changelog_clear 0 || error "changelog_clear failed"
16549
16550         local size1=$(do_facet $SINGLEMDS \
16551                       $LCTL get_param -n mdd.$MDT0.changelog_size)
16552         echo "Changelog size $size1"
16553
16554         rm -rf $DIR/$tdir
16555         $LFS mkdir -i 0 $DIR/$tdir
16556         # change something
16557         mkdir -p $DIR/$tdir/pics/2008/zachy
16558         touch $DIR/$tdir/pics/2008/zachy/timestamp
16559         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
16560         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16561         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16562         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16563         rm $DIR/$tdir/pics/desktop.jpg
16564
16565         local size2=$(do_facet $SINGLEMDS \
16566                       $LCTL get_param -n mdd.$MDT0.changelog_size)
16567         echo "Changelog size after work $size2"
16568
16569         (( $size2 > $size1 )) ||
16570                 error "new Changelog size=$size2 less than old size=$size1"
16571 }
16572 run_test 254 "Check changelog size"
16573
16574 ladvise_no_type()
16575 {
16576         local type=$1
16577         local file=$2
16578
16579         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
16580                 awk -F: '{print $2}' | grep $type > /dev/null
16581         if [ $? -ne 0 ]; then
16582                 return 0
16583         fi
16584         return 1
16585 }
16586
16587 ladvise_no_ioctl()
16588 {
16589         local file=$1
16590
16591         lfs ladvise -a willread $file > /dev/null 2>&1
16592         if [ $? -eq 0 ]; then
16593                 return 1
16594         fi
16595
16596         lfs ladvise -a willread $file 2>&1 |
16597                 grep "Inappropriate ioctl for device" > /dev/null
16598         if [ $? -eq 0 ]; then
16599                 return 0
16600         fi
16601         return 1
16602 }
16603
16604 percent() {
16605         bc <<<"scale=2; ($1 - $2) * 100 / $2"
16606 }
16607
16608 # run a random read IO workload
16609 # usage: random_read_iops <filename> <filesize> <iosize>
16610 random_read_iops() {
16611         local file=$1
16612         local fsize=$2
16613         local iosize=${3:-4096}
16614
16615         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
16616                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
16617 }
16618
16619 drop_file_oss_cache() {
16620         local file="$1"
16621         local nodes="$2"
16622
16623         $LFS ladvise -a dontneed $file 2>/dev/null ||
16624                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
16625 }
16626
16627 ladvise_willread_performance()
16628 {
16629         local repeat=10
16630         local average_origin=0
16631         local average_cache=0
16632         local average_ladvise=0
16633
16634         for ((i = 1; i <= $repeat; i++)); do
16635                 echo "Iter $i/$repeat: reading without willread hint"
16636                 cancel_lru_locks osc
16637                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
16638                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
16639                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
16640                 average_origin=$(bc <<<"$average_origin + $speed_origin")
16641
16642                 cancel_lru_locks osc
16643                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
16644                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
16645                 average_cache=$(bc <<<"$average_cache + $speed_cache")
16646
16647                 cancel_lru_locks osc
16648                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
16649                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
16650                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
16651                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
16652                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
16653         done
16654         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
16655         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
16656         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
16657
16658         speedup_cache=$(percent $average_cache $average_origin)
16659         speedup_ladvise=$(percent $average_ladvise $average_origin)
16660
16661         echo "Average uncached read: $average_origin"
16662         echo "Average speedup with OSS cached read: " \
16663                 "$average_cache = +$speedup_cache%"
16664         echo "Average speedup with ladvise willread: " \
16665                 "$average_ladvise = +$speedup_ladvise%"
16666
16667         local lowest_speedup=20
16668         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
16669                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
16670                         "got $average_cache%. Skipping ladvise willread check."
16671                 return 0
16672         fi
16673
16674         # the test won't work on ZFS until it supports 'ladvise dontneed', but
16675         # it is still good to run until then to exercise 'ladvise willread'
16676         ! $LFS ladvise -a dontneed $DIR/$tfile &&
16677                 [ "$ost1_FSTYPE" = "zfs" ] &&
16678                 echo "osd-zfs does not support dontneed or drop_caches" &&
16679                 return 0
16680
16681         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
16682         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
16683                 error_not_in_vm "Speedup with willread is less than " \
16684                         "$lowest_speedup%, got $average_ladvise%"
16685 }
16686
16687 test_255a() {
16688         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
16689                 skip "lustre < 2.8.54 does not support ladvise "
16690         remote_ost_nodsh && skip "remote OST with nodsh"
16691
16692         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
16693
16694         ladvise_no_type willread $DIR/$tfile &&
16695                 skip "willread ladvise is not supported"
16696
16697         ladvise_no_ioctl $DIR/$tfile &&
16698                 skip "ladvise ioctl is not supported"
16699
16700         local size_mb=100
16701         local size=$((size_mb * 1048576))
16702         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
16703                 error "dd to $DIR/$tfile failed"
16704
16705         lfs ladvise -a willread $DIR/$tfile ||
16706                 error "Ladvise failed with no range argument"
16707
16708         lfs ladvise -a willread -s 0 $DIR/$tfile ||
16709                 error "Ladvise failed with no -l or -e argument"
16710
16711         lfs ladvise -a willread -e 1 $DIR/$tfile ||
16712                 error "Ladvise failed with only -e argument"
16713
16714         lfs ladvise -a willread -l 1 $DIR/$tfile ||
16715                 error "Ladvise failed with only -l argument"
16716
16717         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
16718                 error "End offset should not be smaller than start offset"
16719
16720         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
16721                 error "End offset should not be equal to start offset"
16722
16723         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
16724                 error "Ladvise failed with overflowing -s argument"
16725
16726         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
16727                 error "Ladvise failed with overflowing -e argument"
16728
16729         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
16730                 error "Ladvise failed with overflowing -l argument"
16731
16732         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
16733                 error "Ladvise succeeded with conflicting -l and -e arguments"
16734
16735         echo "Synchronous ladvise should wait"
16736         local delay=4
16737 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
16738         do_nodes $(comma_list $(osts_nodes)) \
16739                 $LCTL set_param fail_val=$delay fail_loc=0x237
16740
16741         local start_ts=$SECONDS
16742         lfs ladvise -a willread $DIR/$tfile ||
16743                 error "Ladvise failed with no range argument"
16744         local end_ts=$SECONDS
16745         local inteval_ts=$((end_ts - start_ts))
16746
16747         if [ $inteval_ts -lt $(($delay - 1)) ]; then
16748                 error "Synchronous advice didn't wait reply"
16749         fi
16750
16751         echo "Asynchronous ladvise shouldn't wait"
16752         local start_ts=$SECONDS
16753         lfs ladvise -a willread -b $DIR/$tfile ||
16754                 error "Ladvise failed with no range argument"
16755         local end_ts=$SECONDS
16756         local inteval_ts=$((end_ts - start_ts))
16757
16758         if [ $inteval_ts -gt $(($delay / 2)) ]; then
16759                 error "Asynchronous advice blocked"
16760         fi
16761
16762         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
16763         ladvise_willread_performance
16764 }
16765 run_test 255a "check 'lfs ladvise -a willread'"
16766
16767 facet_meminfo() {
16768         local facet=$1
16769         local info=$2
16770
16771         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
16772 }
16773
16774 test_255b() {
16775         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
16776                 skip "lustre < 2.8.54 does not support ladvise "
16777         remote_ost_nodsh && skip "remote OST with nodsh"
16778
16779         lfs setstripe -c 1 -i 0 $DIR/$tfile
16780
16781         ladvise_no_type dontneed $DIR/$tfile &&
16782                 skip "dontneed ladvise is not supported"
16783
16784         ladvise_no_ioctl $DIR/$tfile &&
16785                 skip "ladvise ioctl is not supported"
16786
16787         ! $LFS ladvise -a dontneed $DIR/$tfile &&
16788                 [ "$ost1_FSTYPE" = "zfs" ] &&
16789                 skip "zfs-osd does not support 'ladvise dontneed'"
16790
16791         local size_mb=100
16792         local size=$((size_mb * 1048576))
16793         # In order to prevent disturbance of other processes, only check 3/4
16794         # of the memory usage
16795         local kibibytes=$((size_mb * 1024 * 3 / 4))
16796
16797         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
16798                 error "dd to $DIR/$tfile failed"
16799
16800         #force write to complete before dropping OST cache & checking memory
16801         sync
16802
16803         local total=$(facet_meminfo ost1 MemTotal)
16804         echo "Total memory: $total KiB"
16805
16806         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
16807         local before_read=$(facet_meminfo ost1 Cached)
16808         echo "Cache used before read: $before_read KiB"
16809
16810         lfs ladvise -a willread $DIR/$tfile ||
16811                 error "Ladvise willread failed"
16812         local after_read=$(facet_meminfo ost1 Cached)
16813         echo "Cache used after read: $after_read KiB"
16814
16815         lfs ladvise -a dontneed $DIR/$tfile ||
16816                 error "Ladvise dontneed again failed"
16817         local no_read=$(facet_meminfo ost1 Cached)
16818         echo "Cache used after dontneed ladvise: $no_read KiB"
16819
16820         if [ $total -lt $((before_read + kibibytes)) ]; then
16821                 echo "Memory is too small, abort checking"
16822                 return 0
16823         fi
16824
16825         if [ $((before_read + kibibytes)) -gt $after_read ]; then
16826                 error "Ladvise willread should use more memory" \
16827                         "than $kibibytes KiB"
16828         fi
16829
16830         if [ $((no_read + kibibytes)) -gt $after_read ]; then
16831                 error "Ladvise dontneed should release more memory" \
16832                         "than $kibibytes KiB"
16833         fi
16834 }
16835 run_test 255b "check 'lfs ladvise -a dontneed'"
16836
16837 test_255c() {
16838         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
16839                 skip "lustre < 2.10.53 does not support lockahead"
16840
16841         local count
16842         local new_count
16843         local difference
16844         local i
16845         local rc
16846
16847         test_mkdir -p $DIR/$tdir
16848         $LFS setstripe -i 0 $DIR/$tdir
16849
16850         #test 10 returns only success/failure
16851         i=10
16852         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16853         rc=$?
16854         if [ $rc -eq 255 ]; then
16855                 error "Ladvise test${i} failed, ${rc}"
16856         fi
16857
16858         #test 11 counts lock enqueue requests, all others count new locks
16859         i=11
16860         count=$(do_facet ost1 \
16861                 $LCTL get_param -n ost.OSS.ost.stats)
16862         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
16863
16864         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16865         rc=$?
16866         if [ $rc -eq 255 ]; then
16867                 error "Ladvise test${i} failed, ${rc}"
16868         fi
16869
16870         new_count=$(do_facet ost1 \
16871                 $LCTL get_param -n ost.OSS.ost.stats)
16872         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
16873                    awk '{ print $2 }')
16874
16875         difference="$((new_count - count))"
16876         if [ $difference -ne $rc ]; then
16877                 error "Ladvise test${i}, bad enqueue count, returned " \
16878                       "${rc}, actual ${difference}"
16879         fi
16880
16881         for i in $(seq 12 21); do
16882                 # If we do not do this, we run the risk of having too many
16883                 # locks and starting lock cancellation while we are checking
16884                 # lock counts.
16885                 cancel_lru_locks osc
16886
16887                 count=$($LCTL get_param -n \
16888                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
16889
16890                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
16891                 rc=$?
16892                 if [ $rc -eq 255 ]; then
16893                         error "Ladvise test ${i} failed, ${rc}"
16894                 fi
16895
16896                 new_count=$($LCTL get_param -n \
16897                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
16898                 difference="$((new_count - count))"
16899
16900                 # Test 15 output is divided by 100 to map down to valid return
16901                 if [ $i -eq 15 ]; then
16902                         rc="$((rc * 100))"
16903                 fi
16904
16905                 if [ $difference -ne $rc ]; then
16906                         error "Ladvise test ${i}, bad lock count, returned " \
16907                               "${rc}, actual ${difference}"
16908                 fi
16909         done
16910
16911         #test 22 returns only success/failure
16912         i=22
16913         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16914         rc=$?
16915         if [ $rc -eq 255 ]; then
16916                 error "Ladvise test${i} failed, ${rc}"
16917         fi
16918 }
16919 run_test 255c "suite of ladvise lockahead tests"
16920
16921 test_256() {
16922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16923         remote_mds_nodsh && skip "remote MDS with nodsh"
16924         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
16925         changelog_users $SINGLEMDS | grep "^cl" &&
16926                 skip "active changelog user"
16927
16928         local cl_user
16929         local cat_sl
16930         local mdt_dev
16931
16932         mdt_dev=$(mdsdevname 1)
16933         echo $mdt_dev
16934
16935         changelog_register || error "changelog_register failed"
16936
16937         rm -rf $DIR/$tdir
16938         mkdir -p $DIR/$tdir
16939
16940         changelog_clear 0 || error "changelog_clear failed"
16941
16942         # change something
16943         touch $DIR/$tdir/{1..10}
16944
16945         # stop the MDT
16946         stop $SINGLEMDS || error "Fail to stop MDT"
16947
16948         # remount the MDT
16949
16950         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
16951
16952         #after mount new plainllog is used
16953         touch $DIR/$tdir/{11..19}
16954         local tmpfile=$(mktemp -u $tfile.XXXXXX)
16955         cat_sl=$(do_facet $SINGLEMDS "sync; \
16956                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
16957                  llog_reader $tmpfile | grep -c type=1064553b")
16958         do_facet $SINGLEMDS llog_reader $tmpfile
16959
16960         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
16961
16962         changelog_clear 0 || error "changelog_clear failed"
16963
16964         cat_sl=$(do_facet $SINGLEMDS "sync; \
16965                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
16966                  llog_reader $tmpfile | grep -c type=1064553b; rm -f $tmpfile")
16967
16968         if (( cat_sl == 2 )); then
16969                 error "Empty plain llog was not deleted from changelog catalog"
16970         elif (( cat_sl != 1 )); then
16971                 error "Active plain llog shouldn't be deleted from catalog"
16972         fi
16973 }
16974 run_test 256 "Check llog delete for empty and not full state"
16975
16976 test_257() {
16977         remote_mds_nodsh && skip "remote MDS with nodsh"
16978         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
16979                 skip "Need MDS version at least 2.8.55"
16980
16981         test_mkdir $DIR/$tdir
16982
16983         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
16984                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
16985         stat $DIR/$tdir
16986
16987 #define OBD_FAIL_MDS_XATTR_REP                  0x161
16988         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
16989         local facet=mds$((mdtidx + 1))
16990         set_nodes_failloc $(facet_active_host $facet) 0x80000161
16991         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
16992
16993         stop $facet || error "stop MDS failed"
16994         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
16995                 error "start MDS fail"
16996         wait_recovery_complete $facet
16997 }
16998 run_test 257 "xattr locks are not lost"
16999
17000 # Verify we take the i_mutex when security requires it
17001 test_258a() {
17002 #define OBD_FAIL_IMUTEX_SEC 0x141c
17003         $LCTL set_param fail_loc=0x141c
17004         touch $DIR/$tfile
17005         chmod u+s $DIR/$tfile
17006         chmod a+rwx $DIR/$tfile
17007         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17008         RC=$?
17009         if [ $RC -ne 0 ]; then
17010                 error "error, failed to take i_mutex, rc=$?"
17011         fi
17012         rm -f $DIR/$tfile
17013 }
17014 run_test 258a
17015
17016 # Verify we do NOT take the i_mutex in the normal case
17017 test_258b() {
17018 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
17019         $LCTL set_param fail_loc=0x141d
17020         touch $DIR/$tfile
17021         chmod a+rwx $DIR
17022         chmod a+rw $DIR/$tfile
17023         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17024         RC=$?
17025         if [ $RC -ne 0 ]; then
17026                 error "error, took i_mutex unnecessarily, rc=$?"
17027         fi
17028         rm -f $DIR/$tfile
17029
17030 }
17031 run_test 258b "verify i_mutex security behavior"
17032
17033 test_259() {
17034         local file=$DIR/$tfile
17035         local before
17036         local after
17037
17038         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17039
17040         stack_trap "rm -f $file" EXIT
17041
17042         wait_delete_completed
17043         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17044         echo "before: $before"
17045
17046         $LFS setstripe -i 0 -c 1 $file
17047         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
17048         sync_all_data
17049         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17050         echo "after write: $after"
17051
17052 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
17053         do_facet ost1 $LCTL set_param fail_loc=0x2301
17054         $TRUNCATE $file 0
17055         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17056         echo "after truncate: $after"
17057
17058         stop ost1
17059         do_facet ost1 $LCTL set_param fail_loc=0
17060         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17061         sleep 2
17062         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17063         echo "after restart: $after"
17064         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
17065                 error "missing truncate?"
17066
17067         return 0
17068 }
17069 run_test 259 "crash at delayed truncate"
17070
17071 test_260() {
17072 #define OBD_FAIL_MDC_CLOSE               0x806
17073         $LCTL set_param fail_loc=0x80000806
17074         touch $DIR/$tfile
17075
17076 }
17077 run_test 260 "Check mdc_close fail"
17078
17079 ### Data-on-MDT sanity tests ###
17080 test_270a() {
17081         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17082                 skip "Need MDS version at least 2.10.55 for DoM"
17083
17084         # create DoM file
17085         local dom=$DIR/$tdir/dom_file
17086         local tmp=$DIR/$tdir/tmp_file
17087
17088         mkdir -p $DIR/$tdir
17089
17090         # basic checks for DoM component creation
17091         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
17092                 error "Can set MDT layout to non-first entry"
17093
17094         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
17095                 error "Can define multiple entries as MDT layout"
17096
17097         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
17098
17099         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
17100         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
17101         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
17102
17103         local mdtidx=$($LFS getstripe -m $dom)
17104         local mdtname=MDT$(printf %04x $mdtidx)
17105         local facet=mds$((mdtidx + 1))
17106         local space_check=1
17107
17108         # Skip free space checks with ZFS
17109         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
17110
17111         # write
17112         sync
17113         local size_tmp=$((65536 * 3))
17114         local mdtfree1=$(do_facet $facet \
17115                          lctl get_param -n osd*.*$mdtname.kbytesfree)
17116
17117         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17118         # check also direct IO along write
17119         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
17120         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17121         sync
17122         cmp $tmp $dom || error "file data is different"
17123         [ $(stat -c%s $dom) == $size_tmp ] ||
17124                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17125         if [ $space_check == 1 ]; then
17126                 local mdtfree2=$(do_facet $facet \
17127                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
17128
17129                 # increase in usage from by $size_tmp
17130                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17131                         error "MDT free space wrong after write: " \
17132                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17133         fi
17134
17135         # truncate
17136         local size_dom=10000
17137
17138         $TRUNCATE $dom $size_dom
17139         [ $(stat -c%s $dom) == $size_dom ] ||
17140                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
17141         if [ $space_check == 1 ]; then
17142                 mdtfree1=$(do_facet $facet \
17143                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17144                 # decrease in usage from $size_tmp to new $size_dom
17145                 [ $(($mdtfree1 - $mdtfree2)) -ge \
17146                   $(((size_tmp - size_dom) / 1024)) ] ||
17147                         error "MDT free space is wrong after truncate: " \
17148                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
17149         fi
17150
17151         # append
17152         cat $tmp >> $dom
17153         sync
17154         size_dom=$((size_dom + size_tmp))
17155         [ $(stat -c%s $dom) == $size_dom ] ||
17156                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
17157         if [ $space_check == 1 ]; then
17158                 mdtfree2=$(do_facet $facet \
17159                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17160                 # increase in usage by $size_tmp from previous
17161                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17162                         error "MDT free space is wrong after append: " \
17163                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17164         fi
17165
17166         # delete
17167         rm $dom
17168         if [ $space_check == 1 ]; then
17169                 mdtfree1=$(do_facet $facet \
17170                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17171                 # decrease in usage by $size_dom from previous
17172                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
17173                         error "MDT free space is wrong after removal: " \
17174                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
17175         fi
17176
17177         # combined striping
17178         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
17179                 error "Can't create DoM + OST striping"
17180
17181         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
17182         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17183         # check also direct IO along write
17184         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17185         sync
17186         cmp $tmp $dom || error "file data is different"
17187         [ $(stat -c%s $dom) == $size_tmp ] ||
17188                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17189         rm $dom $tmp
17190
17191         return 0
17192 }
17193 run_test 270a "DoM: basic functionality tests"
17194
17195 test_270b() {
17196         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17197                 skip "Need MDS version at least 2.10.55"
17198
17199         local dom=$DIR/$tdir/dom_file
17200         local max_size=1048576
17201
17202         mkdir -p $DIR/$tdir
17203         $LFS setstripe -E $max_size -L mdt $dom
17204
17205         # truncate over the limit
17206         $TRUNCATE $dom $(($max_size + 1)) &&
17207                 error "successful truncate over the maximum size"
17208         # write over the limit
17209         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
17210                 error "successful write over the maximum size"
17211         # append over the limit
17212         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
17213         echo "12345" >> $dom && error "successful append over the maximum size"
17214         rm $dom
17215
17216         return 0
17217 }
17218 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
17219
17220 test_270c() {
17221         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17222                 skip "Need MDS version at least 2.10.55"
17223
17224         mkdir -p $DIR/$tdir
17225         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17226
17227         # check files inherit DoM EA
17228         touch $DIR/$tdir/first
17229         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
17230                 error "bad pattern"
17231         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
17232                 error "bad stripe count"
17233         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
17234                 error "bad stripe size"
17235
17236         # check directory inherits DoM EA and uses it as default
17237         mkdir $DIR/$tdir/subdir
17238         touch $DIR/$tdir/subdir/second
17239         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
17240                 error "bad pattern in sub-directory"
17241         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
17242                 error "bad stripe count in sub-directory"
17243         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
17244                 error "bad stripe size in sub-directory"
17245         return 0
17246 }
17247 run_test 270c "DoM: DoM EA inheritance tests"
17248
17249 test_270d() {
17250         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17251                 skip "Need MDS version at least 2.10.55"
17252
17253         mkdir -p $DIR/$tdir
17254         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17255
17256         # inherit default DoM striping
17257         mkdir $DIR/$tdir/subdir
17258         touch $DIR/$tdir/subdir/f1
17259
17260         # change default directory striping
17261         $LFS setstripe -c 1 $DIR/$tdir/subdir
17262         touch $DIR/$tdir/subdir/f2
17263         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
17264                 error "wrong default striping in file 2"
17265         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
17266                 error "bad pattern in file 2"
17267         return 0
17268 }
17269 run_test 270d "DoM: change striping from DoM to RAID0"
17270
17271 test_270e() {
17272         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17273                 skip "Need MDS version at least 2.10.55"
17274
17275         mkdir -p $DIR/$tdir/dom
17276         mkdir -p $DIR/$tdir/norm
17277         DOMFILES=20
17278         NORMFILES=10
17279         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
17280         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
17281
17282         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
17283         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
17284
17285         # find DoM files by layout
17286         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
17287         [ $NUM -eq  $DOMFILES ] ||
17288                 error "lfs find -L: found $NUM, expected $DOMFILES"
17289         echo "Test 1: lfs find 20 DOM files by layout: OK"
17290
17291         # there should be 1 dir with default DOM striping
17292         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
17293         [ $NUM -eq  1 ] ||
17294                 error "lfs find -L: found $NUM, expected 1 dir"
17295         echo "Test 2: lfs find 1 DOM dir by layout: OK"
17296
17297         # find DoM files by stripe size
17298         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
17299         [ $NUM -eq  $DOMFILES ] ||
17300                 error "lfs find -S: found $NUM, expected $DOMFILES"
17301         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
17302
17303         # find files by stripe offset except DoM files
17304         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
17305         [ $NUM -eq  $NORMFILES ] ||
17306                 error "lfs find -i: found $NUM, expected $NORMFILES"
17307         echo "Test 5: lfs find no DOM files by stripe index: OK"
17308         return 0
17309 }
17310 run_test 270e "DoM: lfs find with DoM files test"
17311
17312 test_270f() {
17313         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17314                 skip "Need MDS version at least 2.10.55"
17315
17316         local mdtname=${FSNAME}-MDT0000-mdtlov
17317         local dom=$DIR/$tdir/dom_file
17318         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
17319                                                 lod.$mdtname.dom_stripesize)
17320         local dom_limit=131072
17321
17322         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
17323         local dom_current=$(do_facet mds1 $LCTL get_param -n \
17324                                                 lod.$mdtname.dom_stripesize)
17325         [ ${dom_limit} -eq ${dom_current} ] ||
17326                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
17327
17328         $LFS mkdir -i 0 -c 1 $DIR/$tdir
17329         $LFS setstripe -d $DIR/$tdir
17330         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
17331                 error "Can't set directory default striping"
17332
17333         # exceed maximum stripe size
17334         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17335                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
17336         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
17337                 error "Able to create DoM component size more than LOD limit"
17338
17339         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
17340         dom_current=$(do_facet mds1 $LCTL get_param -n \
17341                                                 lod.$mdtname.dom_stripesize)
17342         [ 0 -eq ${dom_current} ] ||
17343                 error "Can't set zero DoM stripe limit"
17344         rm $dom
17345
17346         # attempt to create DoM file on server with disabled DoM should
17347         # remove DoM entry from layout and be succeed
17348         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
17349                 error "Can't create DoM file (DoM is disabled)"
17350         [ $($LFS getstripe -L $dom) == "mdt" ] &&
17351                 error "File has DoM component while DoM is disabled"
17352         rm $dom
17353
17354         # attempt to create DoM file with only DoM stripe should return error
17355         $LFS setstripe -E $dom_limit -L mdt $dom &&
17356                 error "Able to create DoM-only file while DoM is disabled"
17357
17358         # too low values to be aligned with smallest stripe size 64K
17359         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
17360         dom_current=$(do_facet mds1 $LCTL get_param -n \
17361                                                 lod.$mdtname.dom_stripesize)
17362         [ 30000 -eq ${dom_current} ] &&
17363                 error "Can set too small DoM stripe limit"
17364
17365         # 64K is a minimal stripe size in Lustre, expect limit of that size
17366         [ 65536 -eq ${dom_current} ] ||
17367                 error "Limit is not set to 64K but ${dom_current}"
17368
17369         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
17370         dom_current=$(do_facet mds1 $LCTL get_param -n \
17371                                                 lod.$mdtname.dom_stripesize)
17372         echo $dom_current
17373         [ 2147483648 -eq ${dom_current} ] &&
17374                 error "Can set too large DoM stripe limit"
17375
17376         do_facet mds1 $LCTL set_param -n \
17377                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
17378         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17379                 error "Can't create DoM component size after limit change"
17380         do_facet mds1 $LCTL set_param -n \
17381                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
17382         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
17383                 error "Can't create DoM file after limit decrease"
17384         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
17385                 error "Can create big DoM component after limit decrease"
17386         touch ${dom}_def ||
17387                 error "Can't create file with old default layout"
17388
17389         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
17390         return 0
17391 }
17392 run_test 270f "DoM: maximum DoM stripe size checks"
17393
17394 test_271a() {
17395         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17396                 skip "Need MDS version at least 2.10.55"
17397
17398         local dom=$DIR/$tdir/dom
17399
17400         mkdir -p $DIR/$tdir
17401
17402         $LFS setstripe -E 1024K -L mdt $dom
17403
17404         lctl set_param -n mdc.*.stats=clear
17405         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17406         cat $dom > /dev/null
17407         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
17408         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
17409         ls $dom
17410         rm -f $dom
17411 }
17412 run_test 271a "DoM: data is cached for read after write"
17413
17414 test_271b() {
17415         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17416                 skip "Need MDS version at least 2.10.55"
17417
17418         local dom=$DIR/$tdir/dom
17419
17420         mkdir -p $DIR/$tdir
17421
17422         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17423
17424         lctl set_param -n mdc.*.stats=clear
17425         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17426         cancel_lru_locks mdc
17427         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
17428         # second stat to check size is cached on client
17429         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
17430         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17431         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
17432         rm -f $dom
17433 }
17434 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
17435
17436 test_271ba() {
17437         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17438                 skip "Need MDS version at least 2.10.55"
17439
17440         local dom=$DIR/$tdir/dom
17441
17442         mkdir -p $DIR/$tdir
17443
17444         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17445
17446         lctl set_param -n mdc.*.stats=clear
17447         lctl set_param -n osc.*.stats=clear
17448         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
17449         cancel_lru_locks mdc
17450         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17451         # second stat to check size is cached on client
17452         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17453         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17454         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
17455         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
17456         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
17457         rm -f $dom
17458 }
17459 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
17460
17461
17462 get_mdc_stats() {
17463         local mdtidx=$1
17464         local param=$2
17465         local mdt=MDT$(printf %04x $mdtidx)
17466
17467         if [ -z $param ]; then
17468                 lctl get_param -n mdc.*$mdt*.stats
17469         else
17470                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
17471         fi
17472 }
17473
17474 test_271c() {
17475         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17476                 skip "Need MDS version at least 2.10.55"
17477
17478         local dom=$DIR/$tdir/dom
17479
17480         mkdir -p $DIR/$tdir
17481
17482         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17483
17484         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17485         local facet=mds$((mdtidx + 1))
17486
17487         cancel_lru_locks mdc
17488         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
17489         createmany -o $dom 1000
17490         lctl set_param -n mdc.*.stats=clear
17491         smalliomany -w $dom 1000 200
17492         get_mdc_stats $mdtidx
17493         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17494         # Each file has 1 open, 1 IO enqueues, total 2000
17495         # but now we have also +1 getxattr for security.capability, total 3000
17496         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
17497         unlinkmany $dom 1000
17498
17499         cancel_lru_locks mdc
17500         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
17501         createmany -o $dom 1000
17502         lctl set_param -n mdc.*.stats=clear
17503         smalliomany -w $dom 1000 200
17504         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17505         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
17506         # for OPEN and IO lock.
17507         [ $((enq - enq_2)) -ge 1000 ] ||
17508                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
17509         unlinkmany $dom 1000
17510         return 0
17511 }
17512 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
17513
17514 cleanup_271def_tests() {
17515         trap 0
17516         rm -f $1
17517 }
17518
17519 test_271d() {
17520         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17521                 skip "Need MDS version at least 2.10.57"
17522
17523         local dom=$DIR/$tdir/dom
17524         local tmp=$TMP/$tfile
17525         trap "cleanup_271def_tests $tmp" EXIT
17526
17527         mkdir -p $DIR/$tdir
17528
17529         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17530
17531         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17532
17533         cancel_lru_locks mdc
17534         dd if=/dev/urandom of=$tmp bs=1000 count=1
17535         dd if=$tmp of=$dom bs=1000 count=1
17536         cancel_lru_locks mdc
17537
17538         cat /etc/hosts >> $tmp
17539         lctl set_param -n mdc.*.stats=clear
17540
17541         # append data to the same file it should update local page
17542         echo "Append to the same page"
17543         cat /etc/hosts >> $dom
17544         local num=$(get_mdc_stats $mdtidx ost_read)
17545         local ra=$(get_mdc_stats $mdtidx req_active)
17546         local rw=$(get_mdc_stats $mdtidx req_waittime)
17547
17548         [ -z $num ] || error "$num READ RPC occured"
17549         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17550         echo "... DONE"
17551
17552         # compare content
17553         cmp $tmp $dom || error "file miscompare"
17554
17555         cancel_lru_locks mdc
17556         lctl set_param -n mdc.*.stats=clear
17557
17558         echo "Open and read file"
17559         cat $dom > /dev/null
17560         local num=$(get_mdc_stats $mdtidx ost_read)
17561         local ra=$(get_mdc_stats $mdtidx req_active)
17562         local rw=$(get_mdc_stats $mdtidx req_waittime)
17563
17564         [ -z $num ] || error "$num READ RPC occured"
17565         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17566         echo "... DONE"
17567
17568         # compare content
17569         cmp $tmp $dom || error "file miscompare"
17570
17571         return 0
17572 }
17573 run_test 271d "DoM: read on open (1K file in reply buffer)"
17574
17575 test_271f() {
17576         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17577                 skip "Need MDS version at least 2.10.57"
17578
17579         local dom=$DIR/$tdir/dom
17580         local tmp=$TMP/$tfile
17581         trap "cleanup_271def_tests $tmp" EXIT
17582
17583         mkdir -p $DIR/$tdir
17584
17585         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17586
17587         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17588
17589         cancel_lru_locks mdc
17590         dd if=/dev/urandom of=$tmp bs=200000 count=1
17591         dd if=$tmp of=$dom bs=200000 count=1
17592         cancel_lru_locks mdc
17593         cat /etc/hosts >> $tmp
17594         lctl set_param -n mdc.*.stats=clear
17595
17596         echo "Append to the same page"
17597         cat /etc/hosts >> $dom
17598         local num=$(get_mdc_stats $mdtidx ost_read)
17599         local ra=$(get_mdc_stats $mdtidx req_active)
17600         local rw=$(get_mdc_stats $mdtidx req_waittime)
17601
17602         [ -z $num ] || error "$num READ RPC occured"
17603         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17604         echo "... DONE"
17605
17606         # compare content
17607         cmp $tmp $dom || error "file miscompare"
17608
17609         cancel_lru_locks mdc
17610         lctl set_param -n mdc.*.stats=clear
17611
17612         echo "Open and read file"
17613         cat $dom > /dev/null
17614         local num=$(get_mdc_stats $mdtidx ost_read)
17615         local ra=$(get_mdc_stats $mdtidx req_active)
17616         local rw=$(get_mdc_stats $mdtidx req_waittime)
17617
17618         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
17619         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17620         echo "... DONE"
17621
17622         # compare content
17623         cmp $tmp $dom || error "file miscompare"
17624
17625         return 0
17626 }
17627 run_test 271f "DoM: read on open (200K file and read tail)"
17628
17629 test_272a() {
17630         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17631                 skip "Need MDS version at least 2.11.50"
17632
17633         local dom=$DIR/$tdir/dom
17634         mkdir -p $DIR/$tdir
17635
17636         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
17637         dd if=/dev/urandom of=$dom bs=512K count=1 ||
17638                 error "failed to write data into $dom"
17639         local old_md5=$(md5sum $dom)
17640
17641         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
17642                 error "failed to migrate to the same DoM component"
17643
17644         local new_md5=$(md5sum $dom)
17645
17646         [ "$old_md5" == "$new_md5" ] ||
17647                 error "md5sum differ: $old_md5, $new_md5"
17648
17649         [ $($LFS getstripe -c $dom) -eq 2 ] ||
17650                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
17651 }
17652 run_test 272a "DoM migration: new layout with the same DOM component"
17653
17654 test_272b() {
17655         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17656                 skip "Need MDS version at least 2.11.50"
17657
17658         local dom=$DIR/$tdir/dom
17659         mkdir -p $DIR/$tdir
17660         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
17661
17662         local mdtidx=$($LFS getstripe -m $dom)
17663         local mdtname=MDT$(printf %04x $mdtidx)
17664         local facet=mds$((mdtidx + 1))
17665
17666         local mdtfree1=$(do_facet $facet \
17667                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17668         dd if=/dev/urandom of=$dom bs=2M count=1 ||
17669                 error "failed to write data into $dom"
17670         local old_md5=$(md5sum $dom)
17671         cancel_lru_locks mdc
17672         local mdtfree1=$(do_facet $facet \
17673                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17674
17675         $LFS migrate -c2 $dom ||
17676                 error "failed to migrate to the new composite layout"
17677         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
17678                 error "MDT stripe was not removed"
17679
17680         cancel_lru_locks mdc
17681         local new_md5=$(md5sum $dom)
17682         [ "$old_md5" != "$new_md5" ] &&
17683                 error "$old_md5 != $new_md5"
17684
17685         # Skip free space checks with ZFS
17686         if [ "$(facet_fstype $facet)" != "zfs" ]; then
17687                 local mdtfree2=$(do_facet $facet \
17688                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17689                 [ $mdtfree2 -gt $mdtfree1 ] ||
17690                         error "MDT space is not freed after migration"
17691         fi
17692         return 0
17693 }
17694 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
17695
17696 test_272c() {
17697         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17698                 skip "Need MDS version at least 2.11.50"
17699
17700         local dom=$DIR/$tdir/$tfile
17701         mkdir -p $DIR/$tdir
17702         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
17703
17704         local mdtidx=$($LFS getstripe -m $dom)
17705         local mdtname=MDT$(printf %04x $mdtidx)
17706         local facet=mds$((mdtidx + 1))
17707
17708         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
17709                 error "failed to write data into $dom"
17710         local old_md5=$(md5sum $dom)
17711         cancel_lru_locks mdc
17712         local mdtfree1=$(do_facet $facet \
17713                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17714
17715         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
17716                 error "failed to migrate to the new composite layout"
17717         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
17718                 error "MDT stripe was not removed"
17719
17720         cancel_lru_locks mdc
17721         local new_md5=$(md5sum $dom)
17722         [ "$old_md5" != "$new_md5" ] &&
17723                 error "$old_md5 != $new_md5"
17724
17725         # Skip free space checks with ZFS
17726         if [ "$(facet_fstype $facet)" != "zfs" ]; then
17727                 local mdtfree2=$(do_facet $facet \
17728                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17729                 [ $mdtfree2 -gt $mdtfree1 ] ||
17730                         error "MDS space is not freed after migration"
17731         fi
17732         return 0
17733 }
17734 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
17735
17736 test_273a() {
17737         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17738                 skip "Need MDS version at least 2.11.50"
17739
17740         # Layout swap cannot be done if either file has DOM component,
17741         # this will never be supported, migration should be used instead
17742
17743         local dom=$DIR/$tdir/$tfile
17744         mkdir -p $DIR/$tdir
17745
17746         $LFS setstripe -c2 ${dom}_plain
17747         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
17748         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
17749                 error "can swap layout with DoM component"
17750         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
17751                 error "can swap layout with DoM component"
17752
17753         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
17754         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
17755                 error "can swap layout with DoM component"
17756         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
17757                 error "can swap layout with DoM component"
17758         return 0
17759 }
17760 run_test 273a "DoM: layout swapping should fail with DOM"
17761
17762 test_275() {
17763         remote_ost_nodsh && skip "remote OST with nodsh"
17764         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
17765                 skip "Need OST version >= 2.10.57"
17766
17767         local file=$DIR/$tfile
17768         local oss
17769
17770         oss=$(comma_list $(osts_nodes))
17771
17772         dd if=/dev/urandom of=$file bs=1M count=2 ||
17773                 error "failed to create a file"
17774         cancel_lru_locks osc
17775
17776         #lock 1
17777         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
17778                 error "failed to read a file"
17779
17780 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
17781         $LCTL set_param fail_loc=0x8000031f
17782
17783         cancel_lru_locks osc &
17784         sleep 1
17785
17786 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
17787         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
17788         #IO takes another lock, but matches the PENDING one
17789         #and places it to the IO RPC
17790         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
17791                 error "failed to read a file with PENDING lock"
17792 }
17793 run_test 275 "Read on a canceled duplicate lock"
17794
17795 test_276() {
17796         remote_ost_nodsh && skip "remote OST with nodsh"
17797         local pid
17798
17799         do_facet ost1 "(while true; do \
17800                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
17801                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
17802         pid=$!
17803
17804         for LOOP in $(seq 20); do
17805                 stop ost1
17806                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
17807         done
17808         kill -9 $pid
17809         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
17810                 rm $TMP/sanity_276_pid"
17811 }
17812 run_test 276 "Race between mount and obd_statfs"
17813
17814 cleanup_test_300() {
17815         trap 0
17816         umask $SAVE_UMASK
17817 }
17818 test_striped_dir() {
17819         local mdt_index=$1
17820         local stripe_count
17821         local stripe_index
17822
17823         mkdir -p $DIR/$tdir
17824
17825         SAVE_UMASK=$(umask)
17826         trap cleanup_test_300 RETURN EXIT
17827
17828         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
17829                                                 $DIR/$tdir/striped_dir ||
17830                 error "set striped dir error"
17831
17832         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
17833         [ "$mode" = "755" ] || error "expect 755 got $mode"
17834
17835         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
17836                 error "getdirstripe failed"
17837         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
17838         if [ "$stripe_count" != "2" ]; then
17839                 error "1:stripe_count is $stripe_count, expect 2"
17840         fi
17841         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
17842         if [ "$stripe_count" != "2" ]; then
17843                 error "2:stripe_count is $stripe_count, expect 2"
17844         fi
17845
17846         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
17847         if [ "$stripe_index" != "$mdt_index" ]; then
17848                 error "stripe_index is $stripe_index, expect $mdt_index"
17849         fi
17850
17851         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
17852                 error "nlink error after create striped dir"
17853
17854         mkdir $DIR/$tdir/striped_dir/a
17855         mkdir $DIR/$tdir/striped_dir/b
17856
17857         stat $DIR/$tdir/striped_dir/a ||
17858                 error "create dir under striped dir failed"
17859         stat $DIR/$tdir/striped_dir/b ||
17860                 error "create dir under striped dir failed"
17861
17862         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
17863                 error "nlink error after mkdir"
17864
17865         rmdir $DIR/$tdir/striped_dir/a
17866         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
17867                 error "nlink error after rmdir"
17868
17869         rmdir $DIR/$tdir/striped_dir/b
17870         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
17871                 error "nlink error after rmdir"
17872
17873         chattr +i $DIR/$tdir/striped_dir
17874         createmany -o $DIR/$tdir/striped_dir/f 10 &&
17875                 error "immutable flags not working under striped dir!"
17876         chattr -i $DIR/$tdir/striped_dir
17877
17878         rmdir $DIR/$tdir/striped_dir ||
17879                 error "rmdir striped dir error"
17880
17881         cleanup_test_300
17882
17883         true
17884 }
17885
17886 test_300a() {
17887         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17888                 skip "skipped for lustre < 2.7.0"
17889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17890         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17891
17892         test_striped_dir 0 || error "failed on striped dir on MDT0"
17893         test_striped_dir 1 || error "failed on striped dir on MDT0"
17894 }
17895 run_test 300a "basic striped dir sanity test"
17896
17897 test_300b() {
17898         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17899                 skip "skipped for lustre < 2.7.0"
17900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17901         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17902
17903         local i
17904         local mtime1
17905         local mtime2
17906         local mtime3
17907
17908         test_mkdir $DIR/$tdir || error "mkdir fail"
17909         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
17910                 error "set striped dir error"
17911         for i in {0..9}; do
17912                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
17913                 sleep 1
17914                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
17915                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
17916                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
17917                 sleep 1
17918                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
17919                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
17920                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
17921         done
17922         true
17923 }
17924 run_test 300b "check ctime/mtime for striped dir"
17925
17926 test_300c() {
17927         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17928                 skip "skipped for lustre < 2.7.0"
17929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17930         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17931
17932         local file_count
17933
17934         mkdir -p $DIR/$tdir
17935         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
17936                 error "set striped dir error"
17937
17938         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
17939                 error "chown striped dir failed"
17940
17941         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
17942                 error "create 5k files failed"
17943
17944         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
17945
17946         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
17947
17948         rm -rf $DIR/$tdir
17949 }
17950 run_test 300c "chown && check ls under striped directory"
17951
17952 test_300d() {
17953         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17954                 skip "skipped for lustre < 2.7.0"
17955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17956         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17957
17958         local stripe_count
17959         local file
17960
17961         mkdir -p $DIR/$tdir
17962         $LFS setstripe -c 2 $DIR/$tdir
17963
17964         #local striped directory
17965         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
17966                 error "set striped dir error"
17967         createmany -o $DIR/$tdir/striped_dir/f 10 ||
17968                 error "create 10 files failed"
17969
17970         #remote striped directory
17971         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
17972                 error "set striped dir error"
17973         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
17974                 error "create 10 files failed"
17975
17976         for file in $(find $DIR/$tdir); do
17977                 stripe_count=$($LFS getstripe -c $file)
17978                 [ $stripe_count -eq 2 ] ||
17979                         error "wrong stripe $stripe_count for $file"
17980         done
17981
17982         rm -rf $DIR/$tdir
17983 }
17984 run_test 300d "check default stripe under striped directory"
17985
17986 test_300e() {
17987         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
17988                 skip "Need MDS version at least 2.7.55"
17989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17990         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17991
17992         local stripe_count
17993         local file
17994
17995         mkdir -p $DIR/$tdir
17996
17997         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
17998                 error "set striped dir error"
17999
18000         touch $DIR/$tdir/striped_dir/a
18001         touch $DIR/$tdir/striped_dir/b
18002         touch $DIR/$tdir/striped_dir/c
18003
18004         mkdir $DIR/$tdir/striped_dir/dir_a
18005         mkdir $DIR/$tdir/striped_dir/dir_b
18006         mkdir $DIR/$tdir/striped_dir/dir_c
18007
18008         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
18009                 error "set striped adir under striped dir error"
18010
18011         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
18012                 error "set striped bdir under striped dir error"
18013
18014         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
18015                 error "set striped cdir under striped dir error"
18016
18017         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
18018                 error "rename dir under striped dir fails"
18019
18020         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
18021                 error "rename dir under different stripes fails"
18022
18023         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
18024                 error "rename file under striped dir should succeed"
18025
18026         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
18027                 error "rename dir under striped dir should succeed"
18028
18029         rm -rf $DIR/$tdir
18030 }
18031 run_test 300e "check rename under striped directory"
18032
18033 test_300f() {
18034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18035         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18036         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18037                 skip "Need MDS version at least 2.7.55"
18038
18039         local stripe_count
18040         local file
18041
18042         rm -rf $DIR/$tdir
18043         mkdir -p $DIR/$tdir
18044
18045         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18046                 error "set striped dir error"
18047
18048         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
18049                 error "set striped dir error"
18050
18051         touch $DIR/$tdir/striped_dir/a
18052         mkdir $DIR/$tdir/striped_dir/dir_a
18053         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
18054                 error "create striped dir under striped dir fails"
18055
18056         touch $DIR/$tdir/striped_dir1/b
18057         mkdir $DIR/$tdir/striped_dir1/dir_b
18058         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
18059                 error "create striped dir under striped dir fails"
18060
18061         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
18062                 error "rename dir under different striped dir should fail"
18063
18064         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
18065                 error "rename striped dir under diff striped dir should fail"
18066
18067         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
18068                 error "rename file under diff striped dirs fails"
18069
18070         rm -rf $DIR/$tdir
18071 }
18072 run_test 300f "check rename cross striped directory"
18073
18074 test_300_check_default_striped_dir()
18075 {
18076         local dirname=$1
18077         local default_count=$2
18078         local default_index=$3
18079         local stripe_count
18080         local stripe_index
18081         local dir_stripe_index
18082         local dir
18083
18084         echo "checking $dirname $default_count $default_index"
18085         $LFS setdirstripe -D -c $default_count -i $default_index \
18086                                 -t all_char $DIR/$tdir/$dirname ||
18087                 error "set default stripe on striped dir error"
18088         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
18089         [ $stripe_count -eq $default_count ] ||
18090                 error "expect $default_count get $stripe_count for $dirname"
18091
18092         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
18093         [ $stripe_index -eq $default_index ] ||
18094                 error "expect $default_index get $stripe_index for $dirname"
18095
18096         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
18097                                                 error "create dirs failed"
18098
18099         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
18100         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
18101         for dir in $(find $DIR/$tdir/$dirname/*); do
18102                 stripe_count=$($LFS getdirstripe -c $dir)
18103                 [ $stripe_count -eq $default_count ] ||
18104                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
18105                 error "stripe count $default_count != $stripe_count for $dir"
18106
18107                 stripe_index=$($LFS getdirstripe -i $dir)
18108                 [ $default_index -eq -1 ] ||
18109                         [ $stripe_index -eq $default_index ] ||
18110                         error "$stripe_index != $default_index for $dir"
18111
18112                 #check default stripe
18113                 stripe_count=$($LFS getdirstripe -D -c $dir)
18114                 [ $stripe_count -eq $default_count ] ||
18115                 error "default count $default_count != $stripe_count for $dir"
18116
18117                 stripe_index=$($LFS getdirstripe -D -i $dir)
18118                 [ $stripe_index -eq $default_index ] ||
18119                 error "default index $default_index != $stripe_index for $dir"
18120         done
18121         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
18122 }
18123
18124 test_300g() {
18125         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18126         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18127                 skip "Need MDS version at least 2.7.55"
18128
18129         local dir
18130         local stripe_count
18131         local stripe_index
18132
18133         mkdir $DIR/$tdir
18134         mkdir $DIR/$tdir/normal_dir
18135
18136         #Checking when client cache stripe index
18137         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
18138         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
18139                 error "create striped_dir failed"
18140
18141         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
18142                 error "create dir0 fails"
18143         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
18144         [ $stripe_index -eq 0 ] ||
18145                 error "dir0 expect index 0 got $stripe_index"
18146
18147         mkdir $DIR/$tdir/striped_dir/dir1 ||
18148                 error "create dir1 fails"
18149         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
18150         [ $stripe_index -eq 1 ] ||
18151                 error "dir1 expect index 1 got $stripe_index"
18152
18153         #check default stripe count/stripe index
18154         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
18155         test_300_check_default_striped_dir normal_dir 1 0
18156         test_300_check_default_striped_dir normal_dir 2 1
18157         test_300_check_default_striped_dir normal_dir 2 -1
18158
18159         #delete default stripe information
18160         echo "delete default stripeEA"
18161         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
18162                 error "set default stripe on striped dir error"
18163
18164         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
18165         for dir in $(find $DIR/$tdir/normal_dir/*); do
18166                 stripe_count=$($LFS getdirstripe -c $dir)
18167                 [ $stripe_count -eq 0 ] ||
18168                         error "expect 1 get $stripe_count for $dir"
18169                 stripe_index=$($LFS getdirstripe -i $dir)
18170                 [ $stripe_index -eq 0 ] ||
18171                         error "expect 0 get $stripe_index for $dir"
18172         done
18173 }
18174 run_test 300g "check default striped directory for normal directory"
18175
18176 test_300h() {
18177         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18178         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18179                 skip "Need MDS version at least 2.7.55"
18180
18181         local dir
18182         local stripe_count
18183
18184         mkdir $DIR/$tdir
18185         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18186                 error "set striped dir error"
18187
18188         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
18189         test_300_check_default_striped_dir striped_dir 1 0
18190         test_300_check_default_striped_dir striped_dir 2 1
18191         test_300_check_default_striped_dir striped_dir 2 -1
18192
18193         #delete default stripe information
18194         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
18195                 error "set default stripe on striped dir error"
18196
18197         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
18198         for dir in $(find $DIR/$tdir/striped_dir/*); do
18199                 stripe_count=$($LFS getdirstripe -c $dir)
18200                 [ $stripe_count -eq 0 ] ||
18201                         error "expect 1 get $stripe_count for $dir"
18202         done
18203 }
18204 run_test 300h "check default striped directory for striped directory"
18205
18206 test_300i() {
18207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18208         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18209         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18210                 skip "Need MDS version at least 2.7.55"
18211
18212         local stripe_count
18213         local file
18214
18215         mkdir $DIR/$tdir
18216
18217         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18218                 error "set striped dir error"
18219
18220         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18221                 error "create files under striped dir failed"
18222
18223         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
18224                 error "set striped hashdir error"
18225
18226         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
18227                 error "create dir0 under hash dir failed"
18228         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
18229                 error "create dir1 under hash dir failed"
18230
18231         # unfortunately, we need to umount to clear dir layout cache for now
18232         # once we fully implement dir layout, we can drop this
18233         umount_client $MOUNT || error "umount failed"
18234         mount_client $MOUNT || error "mount failed"
18235
18236         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
18237         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
18238         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
18239
18240         #set the stripe to be unknown hash type
18241         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
18242         $LCTL set_param fail_loc=0x1901
18243         for ((i = 0; i < 10; i++)); do
18244                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
18245                         error "stat f-$i failed"
18246                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
18247         done
18248
18249         touch $DIR/$tdir/striped_dir/f0 &&
18250                 error "create under striped dir with unknown hash should fail"
18251
18252         $LCTL set_param fail_loc=0
18253
18254         umount_client $MOUNT || error "umount failed"
18255         mount_client $MOUNT || error "mount failed"
18256
18257         return 0
18258 }
18259 run_test 300i "client handle unknown hash type striped directory"
18260
18261 test_300j() {
18262         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18264         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18265                 skip "Need MDS version at least 2.7.55"
18266
18267         local stripe_count
18268         local file
18269
18270         mkdir $DIR/$tdir
18271
18272         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
18273         $LCTL set_param fail_loc=0x1702
18274         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18275                 error "set striped dir error"
18276
18277         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18278                 error "create files under striped dir failed"
18279
18280         $LCTL set_param fail_loc=0
18281
18282         rm -rf $DIR/$tdir || error "unlink striped dir fails"
18283
18284         return 0
18285 }
18286 run_test 300j "test large update record"
18287
18288 test_300k() {
18289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18290         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18291         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18292                 skip "Need MDS version at least 2.7.55"
18293
18294         # this test needs a huge transaction
18295         local kb
18296         kb=$(do_facet $SINGLEMDS lctl get_param -n osd*.lustre-MDT0000.kbytestotal)
18297         [ $kb -lt $((1024*1024)) ] && skip "too small mds: $kb"
18298
18299         local stripe_count
18300         local file
18301
18302         mkdir $DIR/$tdir
18303
18304         #define OBD_FAIL_LARGE_STRIPE   0x1703
18305         $LCTL set_param fail_loc=0x1703
18306         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
18307                 error "set striped dir error"
18308         $LCTL set_param fail_loc=0
18309
18310         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18311                 error "getstripeddir fails"
18312         rm -rf $DIR/$tdir/striped_dir ||
18313                 error "unlink striped dir fails"
18314
18315         return 0
18316 }
18317 run_test 300k "test large striped directory"
18318
18319 test_300l() {
18320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18321         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18322         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18323                 skip "Need MDS version at least 2.7.55"
18324
18325         local stripe_index
18326
18327         test_mkdir -p $DIR/$tdir/striped_dir
18328         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
18329                         error "chown $RUNAS_ID failed"
18330         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
18331                 error "set default striped dir failed"
18332
18333         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
18334         $LCTL set_param fail_loc=0x80000158
18335         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
18336
18337         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
18338         [ $stripe_index -eq 1 ] ||
18339                 error "expect 1 get $stripe_index for $dir"
18340 }
18341 run_test 300l "non-root user to create dir under striped dir with stale layout"
18342
18343 test_300m() {
18344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18345         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
18346         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18347                 skip "Need MDS version at least 2.7.55"
18348
18349         mkdir -p $DIR/$tdir/striped_dir
18350         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
18351                 error "set default stripes dir error"
18352
18353         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
18354
18355         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
18356         [ $stripe_count -eq 0 ] ||
18357                         error "expect 0 get $stripe_count for a"
18358
18359         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
18360                 error "set default stripes dir error"
18361
18362         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
18363
18364         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
18365         [ $stripe_count -eq 0 ] ||
18366                         error "expect 0 get $stripe_count for b"
18367
18368         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
18369                 error "set default stripes dir error"
18370
18371         mkdir $DIR/$tdir/striped_dir/c &&
18372                 error "default stripe_index is invalid, mkdir c should fails"
18373
18374         rm -rf $DIR/$tdir || error "rmdir fails"
18375 }
18376 run_test 300m "setstriped directory on single MDT FS"
18377
18378 cleanup_300n() {
18379         local list=$(comma_list $(mdts_nodes))
18380
18381         trap 0
18382         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18383 }
18384
18385 test_300n() {
18386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18387         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18388         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18389                 skip "Need MDS version at least 2.7.55"
18390         remote_mds_nodsh && skip "remote MDS with nodsh"
18391
18392         local stripe_index
18393         local list=$(comma_list $(mdts_nodes))
18394
18395         trap cleanup_300n RETURN EXIT
18396         mkdir -p $DIR/$tdir
18397         chmod 777 $DIR/$tdir
18398         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
18399                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18400                 error "create striped dir succeeds with gid=0"
18401
18402         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18403         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
18404                 error "create striped dir fails with gid=-1"
18405
18406         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18407         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
18408                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18409                 error "set default striped dir succeeds with gid=0"
18410
18411
18412         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18413         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
18414                 error "set default striped dir fails with gid=-1"
18415
18416
18417         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18418         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
18419                                         error "create test_dir fails"
18420         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
18421                                         error "create test_dir1 fails"
18422         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
18423                                         error "create test_dir2 fails"
18424         cleanup_300n
18425 }
18426 run_test 300n "non-root user to create dir under striped dir with default EA"
18427
18428 test_300o() {
18429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18430         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18431         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18432                 skip "Need MDS version at least 2.7.55"
18433
18434         local numfree1
18435         local numfree2
18436
18437         mkdir -p $DIR/$tdir
18438
18439         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
18440         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
18441         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
18442                 skip "not enough free inodes $numfree1 $numfree2"
18443         fi
18444
18445         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
18446         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
18447         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
18448                 skip "not enough free space $numfree1 $numfree2"
18449         fi
18450
18451         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
18452                 error "setdirstripe fails"
18453
18454         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
18455                 error "create dirs fails"
18456
18457         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
18458         ls $DIR/$tdir/striped_dir > /dev/null ||
18459                 error "ls striped dir fails"
18460         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
18461                 error "unlink big striped dir fails"
18462 }
18463 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
18464
18465 test_300p() {
18466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18467         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18468         remote_mds_nodsh && skip "remote MDS with nodsh"
18469
18470         mkdir -p $DIR/$tdir
18471
18472         #define OBD_FAIL_OUT_ENOSPC     0x1704
18473         do_facet mds2 lctl set_param fail_loc=0x80001704
18474         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
18475                  && error "create striped directory should fail"
18476
18477         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
18478
18479         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
18480         true
18481 }
18482 run_test 300p "create striped directory without space"
18483
18484 test_300q() {
18485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18486         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18487
18488         local fd=$(free_fd)
18489         local cmd="exec $fd<$tdir"
18490         cd $DIR
18491         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
18492         eval $cmd
18493         cmd="exec $fd<&-"
18494         trap "eval $cmd" EXIT
18495         cd $tdir || error "cd $tdir fails"
18496         rmdir  ../$tdir || error "rmdir $tdir fails"
18497         mkdir local_dir && error "create dir succeeds"
18498         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
18499         eval $cmd
18500         return 0
18501 }
18502 run_test 300q "create remote directory under orphan directory"
18503
18504 test_300r() {
18505         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
18506                 skip "Need MDS version at least 2.7.55" && return
18507         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18508
18509         mkdir $DIR/$tdir
18510
18511         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
18512                 error "set striped dir error"
18513
18514         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18515                 error "getstripeddir fails"
18516
18517         local stripe_count
18518         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18519                       awk '/lmv_stripe_count:/ { print $2 }')
18520
18521         [ $MDSCOUNT -ne $stripe_count ] &&
18522                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
18523
18524         rm -rf $DIR/$tdir/striped_dir ||
18525                 error "unlink striped dir fails"
18526 }
18527 run_test 300r "test -1 striped directory"
18528
18529 prepare_remote_file() {
18530         mkdir $DIR/$tdir/src_dir ||
18531                 error "create remote source failed"
18532
18533         cp /etc/hosts $DIR/$tdir/src_dir/a ||
18534                  error "cp to remote source failed"
18535         touch $DIR/$tdir/src_dir/a
18536
18537         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
18538                 error "create remote target dir failed"
18539
18540         touch $DIR/$tdir/tgt_dir/b
18541
18542         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
18543                 error "rename dir cross MDT failed!"
18544
18545         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
18546                 error "src_child still exists after rename"
18547
18548         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
18549                 error "missing file(a) after rename"
18550
18551         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
18552                 error "diff after rename"
18553 }
18554
18555 test_310a() {
18556         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
18557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18558
18559         local remote_file=$DIR/$tdir/tgt_dir/b
18560
18561         mkdir -p $DIR/$tdir
18562
18563         prepare_remote_file || error "prepare remote file failed"
18564
18565         #open-unlink file
18566         $OPENUNLINK $remote_file $remote_file ||
18567                 error "openunlink $remote_file failed"
18568         $CHECKSTAT -a $remote_file || error "$remote_file exists"
18569 }
18570 run_test 310a "open unlink remote file"
18571
18572 test_310b() {
18573         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
18574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18575
18576         local remote_file=$DIR/$tdir/tgt_dir/b
18577
18578         mkdir -p $DIR/$tdir
18579
18580         prepare_remote_file || error "prepare remote file failed"
18581
18582         ln $remote_file $DIR/$tfile || error "link failed for remote file"
18583         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
18584         $CHECKSTAT -t file $remote_file || error "check file failed"
18585 }
18586 run_test 310b "unlink remote file with multiple links while open"
18587
18588 test_310c() {
18589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18590         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
18591
18592         local remote_file=$DIR/$tdir/tgt_dir/b
18593
18594         mkdir -p $DIR/$tdir
18595
18596         prepare_remote_file || error "prepare remote file failed"
18597
18598         ln $remote_file $DIR/$tfile || error "link failed for remote file"
18599         multiop_bg_pause $remote_file O_uc ||
18600                         error "mulitop failed for remote file"
18601         MULTIPID=$!
18602         $MULTIOP $DIR/$tfile Ouc
18603         kill -USR1 $MULTIPID
18604         wait $MULTIPID
18605 }
18606 run_test 310c "open-unlink remote file with multiple links"
18607
18608 #LU-4825
18609 test_311() {
18610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18611         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
18612         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
18613                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
18614         remote_mds_nodsh && skip "remote MDS with nodsh"
18615
18616         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
18617         local mdts=$(comma_list $(mdts_nodes))
18618
18619         mkdir -p $DIR/$tdir
18620         $LFS setstripe -i 0 -c 1 $DIR/$tdir
18621         createmany -o $DIR/$tdir/$tfile. 1000
18622
18623         # statfs data is not real time, let's just calculate it
18624         old_iused=$((old_iused + 1000))
18625
18626         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
18627                         osp.*OST0000*MDT0000.create_count")
18628         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
18629                                 osp.*OST0000*MDT0000.max_create_count")
18630         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
18631
18632         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
18633         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
18634         [ $index -ne 0 ] || error "$tfile stripe index is 0"
18635
18636         unlinkmany $DIR/$tdir/$tfile. 1000
18637
18638         do_nodes $mdts "$LCTL set_param -n \
18639                         osp.*OST0000*.max_create_count=$max_count"
18640         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
18641                 do_nodes $mdts "$LCTL set_param -n \
18642                                 osp.*OST0000*.create_count=$count"
18643         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
18644                         grep "=0" && error "create_count is zero"
18645
18646         local new_iused
18647         for i in $(seq 120); do
18648                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
18649                 # system may be too busy to destroy all objs in time, use
18650                 # a somewhat small value to not fail autotest
18651                 [ $((old_iused - new_iused)) -gt 400 ] && break
18652                 sleep 1
18653         done
18654
18655         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
18656         [ $((old_iused - new_iused)) -gt 400 ] ||
18657                 error "objs not destroyed after unlink"
18658 }
18659 run_test 311 "disable OSP precreate, and unlink should destroy objs"
18660
18661 zfs_oid_to_objid()
18662 {
18663         local ost=$1
18664         local objid=$2
18665
18666         local vdevdir=$(dirname $(facet_vdevice $ost))
18667         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
18668         local zfs_zapid=$(do_facet $ost $cmd |
18669                           grep -w "/O/0/d$((objid%32))" -C 5 |
18670                           awk '/Object/{getline; print $1}')
18671         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
18672                           awk "/$objid = /"'{printf $3}')
18673
18674         echo $zfs_objid
18675 }
18676
18677 zfs_object_blksz() {
18678         local ost=$1
18679         local objid=$2
18680
18681         local vdevdir=$(dirname $(facet_vdevice $ost))
18682         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
18683         local blksz=$(do_facet $ost $cmd $objid |
18684                       awk '/dblk/{getline; printf $4}')
18685
18686         case "${blksz: -1}" in
18687                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
18688                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
18689                 *) ;;
18690         esac
18691
18692         echo $blksz
18693 }
18694
18695 test_312() { # LU-4856
18696         remote_ost_nodsh && skip "remote OST with nodsh"
18697         [ "$ost1_FSTYPE" = "zfs" ] ||
18698                 skip_env "the test only applies to zfs"
18699
18700         local max_blksz=$(do_facet ost1 \
18701                           $ZFS get -p recordsize $(facet_device ost1) |
18702                           awk '!/VALUE/{print $3}')
18703
18704         # to make life a little bit easier
18705         $LFS mkdir -c 1 -i 0 $DIR/$tdir
18706         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18707
18708         local tf=$DIR/$tdir/$tfile
18709         touch $tf
18710         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18711
18712         # Get ZFS object id
18713         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18714         # block size change by sequential overwrite
18715         local bs
18716
18717         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
18718                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
18719
18720                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
18721                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
18722         done
18723         rm -f $tf
18724
18725         # block size change by sequential append write
18726         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
18727         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18728         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18729         local count
18730
18731         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
18732                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
18733                         oflag=sync conv=notrunc
18734
18735                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
18736                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
18737                         error "blksz error, actual $blksz, " \
18738                                 "expected: 2 * $count * $PAGE_SIZE"
18739         done
18740         rm -f $tf
18741
18742         # random write
18743         touch $tf
18744         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18745         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18746
18747         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
18748         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18749         [ $blksz -eq $PAGE_SIZE ] ||
18750                 error "blksz error: $blksz, expected: $PAGE_SIZE"
18751
18752         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
18753         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18754         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
18755
18756         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
18757         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18758         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
18759 }
18760 run_test 312 "make sure ZFS adjusts its block size by write pattern"
18761
18762 test_313() {
18763         remote_ost_nodsh && skip "remote OST with nodsh"
18764
18765         local file=$DIR/$tfile
18766
18767         rm -f $file
18768         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
18769
18770         # define OBD_FAIL_TGT_RCVD_EIO           0x720
18771         do_facet ost1 "$LCTL set_param fail_loc=0x720"
18772         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
18773                 error "write should failed"
18774         do_facet ost1 "$LCTL set_param fail_loc=0"
18775         rm -f $file
18776 }
18777 run_test 313 "io should fail after last_rcvd update fail"
18778
18779 test_314() {
18780         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
18781
18782         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
18783         do_facet ost1 "$LCTL set_param fail_loc=0x720"
18784         rm -f $DIR/$tfile
18785         wait_delete_completed
18786         do_facet ost1 "$LCTL set_param fail_loc=0"
18787 }
18788 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
18789
18790 test_315() { # LU-618
18791         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
18792
18793         local file=$DIR/$tfile
18794         rm -f $file
18795
18796         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
18797                 error "multiop file write failed"
18798         $MULTIOP $file oO_RDONLY:r4063232_c &
18799         PID=$!
18800
18801         sleep 2
18802
18803         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
18804         kill -USR1 $PID
18805
18806         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
18807         rm -f $file
18808 }
18809 run_test 315 "read should be accounted"
18810
18811 test_316() {
18812         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18813         large_xattr_enabled || skip_env "ea_inode feature disabled"
18814
18815         rm -rf $DIR/$tdir/d
18816         mkdir -p $DIR/$tdir/d
18817         chown nobody $DIR/$tdir/d
18818         touch $DIR/$tdir/d/file
18819
18820         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
18821 }
18822 run_test 316 "lfs mv"
18823
18824 test_317() {
18825         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
18826                 skip "Need MDS version at least 2.11.53"
18827         local trunc_sz
18828         local grant_blk_size
18829
18830         if [ "$(facet_fstype $facet)" == "zfs" ]; then
18831                 skip "LU-10370: no implementation for ZFS" && return
18832         fi
18833
18834         stack_trap "rm -f $DIR/$tfile" EXIT
18835         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
18836                         awk '/grant_block_size:/ { print $2; exit; }')
18837         #
18838         # Create File of size 5M. Truncate it to below size's and verify
18839         # blocks count.
18840         #
18841         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
18842                 error "Create file : $DIR/$tfile"
18843
18844         for trunc_sz in 2097152 4097 4000 509 0; do
18845                 $TRUNCATE $DIR/$tfile $trunc_sz ||
18846                         error "truncate $tfile to $trunc_sz failed"
18847                 local sz=$(stat --format=%s $DIR/$tfile)
18848                 local blk=$(stat --format=%b $DIR/$tfile)
18849                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
18850                                      grant_blk_size) * 8))
18851
18852                 if [[ $blk -ne $trunc_blk ]]; then
18853                         $(which stat) $DIR/$tfile
18854                         error "Expected Block $trunc_blk got $blk for $tfile"
18855                 fi
18856
18857                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
18858                         error "Expected Size $trunc_sz got $sz for $tfile"
18859         done
18860
18861         #
18862         # sparse file test
18863         # Create file with a hole and write actual two blocks. Block count
18864         # must be 16.
18865         #
18866         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
18867                 conv=fsync || error "Create file : $DIR/$tfile"
18868
18869         # Calculate the final truncate size.
18870         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
18871
18872         #
18873         # truncate to size $trunc_sz bytes. Strip the last block
18874         # The block count must drop to 8
18875         #
18876         $TRUNCATE $DIR/$tfile $trunc_sz ||
18877                 error "truncate $tfile to $trunc_sz failed"
18878
18879         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
18880         sz=$(stat --format=%s $DIR/$tfile)
18881         blk=$(stat --format=%b $DIR/$tfile)
18882
18883         if [[ $blk -ne $trunc_bsz ]]; then
18884                 $(which stat) $DIR/$tfile
18885                 error "Expected Block $trunc_bsz got $blk for $tfile"
18886         fi
18887
18888         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
18889                 error "Expected Size $trunc_sz got $sz for $tfile"
18890 }
18891 run_test 317 "Verify blocks get correctly update after truncate"
18892
18893 test_319() {
18894         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
18895
18896         local before=$(date +%s)
18897         local evict
18898         local mdir=$DIR/$tdir
18899         local file=$mdir/xxx
18900
18901         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
18902         touch $file
18903
18904 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
18905         $LCTL set_param fail_val=5 fail_loc=0x8000032c
18906         $LFS mv -m1 $file &
18907
18908         sleep 1
18909         dd if=$file of=/dev/null
18910         wait
18911         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
18912           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
18913
18914         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
18915 }
18916 run_test 319 "lost lease lock on migrate error"
18917
18918 test_fake_rw() {
18919         local read_write=$1
18920         if [ "$read_write" = "write" ]; then
18921                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
18922         elif [ "$read_write" = "read" ]; then
18923                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
18924         else
18925                 error "argument error"
18926         fi
18927
18928         # turn off debug for performance testing
18929         local saved_debug=$($LCTL get_param -n debug)
18930         $LCTL set_param debug=0
18931
18932         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18933
18934         # get ost1 size - lustre-OST0000
18935         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
18936         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
18937         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
18938
18939         if [ "$read_write" = "read" ]; then
18940                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
18941         fi
18942
18943         local start_time=$(date +%s.%N)
18944         $dd_cmd bs=1M count=$blocks oflag=sync ||
18945                 error "real dd $read_write error"
18946         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
18947
18948         if [ "$read_write" = "write" ]; then
18949                 rm -f $DIR/$tfile
18950         fi
18951
18952         # define OBD_FAIL_OST_FAKE_RW           0x238
18953         do_facet ost1 $LCTL set_param fail_loc=0x238
18954
18955         local start_time=$(date +%s.%N)
18956         $dd_cmd bs=1M count=$blocks oflag=sync ||
18957                 error "fake dd $read_write error"
18958         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
18959
18960         if [ "$read_write" = "write" ]; then
18961                 # verify file size
18962                 cancel_lru_locks osc
18963                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
18964                         error "$tfile size not $blocks MB"
18965         fi
18966         do_facet ost1 $LCTL set_param fail_loc=0
18967
18968         echo "fake $read_write $duration_fake vs. normal $read_write" \
18969                 "$duration in seconds"
18970         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
18971                 error_not_in_vm "fake write is slower"
18972
18973         $LCTL set_param -n debug="$saved_debug"
18974         rm -f $DIR/$tfile
18975 }
18976 test_399a() { # LU-7655 for OST fake write
18977         remote_ost_nodsh && skip "remote OST with nodsh"
18978
18979         test_fake_rw write
18980 }
18981 run_test 399a "fake write should not be slower than normal write"
18982
18983 test_399b() { # LU-8726 for OST fake read
18984         remote_ost_nodsh && skip "remote OST with nodsh"
18985         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
18986                 skip_env "ldiskfs only test"
18987         fi
18988
18989         test_fake_rw read
18990 }
18991 run_test 399b "fake read should not be slower than normal read"
18992
18993 test_400a() { # LU-1606, was conf-sanity test_74
18994         if ! which $CC > /dev/null 2>&1; then
18995                 skip_env "$CC is not installed"
18996         fi
18997
18998         local extra_flags=''
18999         local out=$TMP/$tfile
19000         local prefix=/usr/include/lustre
19001         local prog
19002
19003         if ! [[ -d $prefix ]]; then
19004                 # Assume we're running in tree and fixup the include path.
19005                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
19006                 extra_flags+=" -L$LUSTRE/utils/.lib"
19007         fi
19008
19009         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
19010                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
19011                         error "client api broken"
19012         done
19013         rm -f $out
19014 }
19015 run_test 400a "Lustre client api program can compile and link"
19016
19017 test_400b() { # LU-1606, LU-5011
19018         local header
19019         local out=$TMP/$tfile
19020         local prefix=/usr/include/linux/lustre
19021
19022         # We use a hard coded prefix so that this test will not fail
19023         # when run in tree. There are headers in lustre/include/lustre/
19024         # that are not packaged (like lustre_idl.h) and have more
19025         # complicated include dependencies (like config.h and lnet/types.h).
19026         # Since this test about correct packaging we just skip them when
19027         # they don't exist (see below) rather than try to fixup cppflags.
19028
19029         if ! which $CC > /dev/null 2>&1; then
19030                 skip_env "$CC is not installed"
19031         fi
19032
19033         for header in $prefix/*.h; do
19034                 if ! [[ -f "$header" ]]; then
19035                         continue
19036                 fi
19037
19038                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
19039                         continue # lustre_ioctl.h is internal header
19040                 fi
19041
19042                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
19043                         error "cannot compile '$header'"
19044         done
19045         rm -f $out
19046 }
19047 run_test 400b "packaged headers can be compiled"
19048
19049 test_401a() { #LU-7437
19050         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
19051         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
19052
19053         #count the number of parameters by "list_param -R"
19054         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
19055         #count the number of parameters by listing proc files
19056         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
19057         echo "proc_dirs='$proc_dirs'"
19058         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
19059         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
19060                       sort -u | wc -l)
19061
19062         [ $params -eq $procs ] ||
19063                 error "found $params parameters vs. $procs proc files"
19064
19065         # test the list_param -D option only returns directories
19066         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
19067         #count the number of parameters by listing proc directories
19068         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
19069                 sort -u | wc -l)
19070
19071         [ $params -eq $procs ] ||
19072                 error "found $params parameters vs. $procs proc files"
19073 }
19074 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
19075
19076 test_401b() {
19077         local save=$($LCTL get_param -n jobid_var)
19078         local tmp=testing
19079
19080         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
19081                 error "no error returned when setting bad parameters"
19082
19083         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
19084         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
19085
19086         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
19087         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
19088         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
19089 }
19090 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
19091
19092 test_401c() {
19093         local jobid_var_old=$($LCTL get_param -n jobid_var)
19094         local jobid_var_new
19095
19096         $LCTL set_param jobid_var= &&
19097                 error "no error returned for 'set_param a='"
19098
19099         jobid_var_new=$($LCTL get_param -n jobid_var)
19100         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19101                 error "jobid_var was changed by setting without value"
19102
19103         $LCTL set_param jobid_var &&
19104                 error "no error returned for 'set_param a'"
19105
19106         jobid_var_new=$($LCTL get_param -n jobid_var)
19107         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19108                 error "jobid_var was changed by setting without value"
19109 }
19110 run_test 401c "Verify 'lctl set_param' without value fails in either format."
19111
19112 test_401d() {
19113         local jobid_var_old=$($LCTL get_param -n jobid_var)
19114         local jobid_var_new
19115         local new_value="foo=bar"
19116
19117         $LCTL set_param jobid_var=$new_value ||
19118                 error "'set_param a=b' did not accept a value containing '='"
19119
19120         jobid_var_new=$($LCTL get_param -n jobid_var)
19121         [[ "$jobid_var_new" == "$new_value" ]] ||
19122                 error "'set_param a=b' failed on a value containing '='"
19123
19124         # Reset the jobid_var to test the other format
19125         $LCTL set_param jobid_var=$jobid_var_old
19126         jobid_var_new=$($LCTL get_param -n jobid_var)
19127         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19128                 error "failed to reset jobid_var"
19129
19130         $LCTL set_param jobid_var $new_value ||
19131                 error "'set_param a b' did not accept a value containing '='"
19132
19133         jobid_var_new=$($LCTL get_param -n jobid_var)
19134         [[ "$jobid_var_new" == "$new_value" ]] ||
19135                 error "'set_param a b' failed on a value containing '='"
19136
19137         $LCTL set_param jobid_var $jobid_var_old
19138         jobid_var_new=$($LCTL get_param -n jobid_var)
19139         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19140                 error "failed to reset jobid_var"
19141 }
19142 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
19143
19144 test_402() {
19145         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
19146         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
19147                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
19148         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
19149                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
19150                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
19151         remote_mds_nodsh && skip "remote MDS with nodsh"
19152
19153         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
19154 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
19155         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
19156         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
19157                 echo "Touch failed - OK"
19158 }
19159 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
19160
19161 test_403() {
19162         local file1=$DIR/$tfile.1
19163         local file2=$DIR/$tfile.2
19164         local tfile=$TMP/$tfile
19165
19166         rm -f $file1 $file2 $tfile
19167
19168         touch $file1
19169         ln $file1 $file2
19170
19171         # 30 sec OBD_TIMEOUT in ll_getattr()
19172         # right before populating st_nlink
19173         $LCTL set_param fail_loc=0x80001409
19174         stat -c %h $file1 > $tfile &
19175
19176         # create an alias, drop all locks and reclaim the dentry
19177         < $file2
19178         cancel_lru_locks mdc
19179         cancel_lru_locks osc
19180         sysctl -w vm.drop_caches=2
19181
19182         wait
19183
19184         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
19185
19186         rm -f $tfile $file1 $file2
19187 }
19188 run_test 403 "i_nlink should not drop to zero due to aliasing"
19189
19190 test_404() { # LU-6601
19191         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
19192                 skip "Need server version newer than 2.8.52"
19193         remote_mds_nodsh && skip "remote MDS with nodsh"
19194
19195         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
19196                 awk '/osp .*-osc-MDT/ { print $4}')
19197
19198         local osp
19199         for osp in $mosps; do
19200                 echo "Deactivate: " $osp
19201                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
19202                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19203                         awk -vp=$osp '$4 == p { print $2 }')
19204                 [ $stat = IN ] || {
19205                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19206                         error "deactivate error"
19207                 }
19208                 echo "Activate: " $osp
19209                 do_facet $SINGLEMDS $LCTL --device %$osp activate
19210                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19211                         awk -vp=$osp '$4 == p { print $2 }')
19212                 [ $stat = UP ] || {
19213                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19214                         error "activate error"
19215                 }
19216         done
19217 }
19218 run_test 404 "validate manual {de}activated works properly for OSPs"
19219
19220 test_405() {
19221         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19222         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
19223                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
19224                         skip "Layout swap lock is not supported"
19225
19226         check_swap_layouts_support
19227
19228         test_mkdir $DIR/$tdir
19229         swap_lock_test -d $DIR/$tdir ||
19230                 error "One layout swap locked test failed"
19231 }
19232 run_test 405 "Various layout swap lock tests"
19233
19234 test_406() {
19235         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19236         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19237         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19239         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
19240                 skip "Need MDS version at least 2.8.50"
19241
19242         local def_stripe_size=$($LFS getstripe -S $MOUNT)
19243         local test_pool=$TESTNAME
19244
19245         if ! combined_mgs_mds ; then
19246                 mount_mgs_client
19247         fi
19248         pool_add $test_pool || error "pool_add failed"
19249         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
19250                 error "pool_add_targets failed"
19251
19252         save_layout_restore_at_exit $MOUNT
19253
19254         # parent set default stripe count only, child will stripe from both
19255         # parent and fs default
19256         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
19257                 error "setstripe $MOUNT failed"
19258         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
19259         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
19260         for i in $(seq 10); do
19261                 local f=$DIR/$tdir/$tfile.$i
19262                 touch $f || error "touch failed"
19263                 local count=$($LFS getstripe -c $f)
19264                 [ $count -eq $OSTCOUNT ] ||
19265                         error "$f stripe count $count != $OSTCOUNT"
19266                 local offset=$($LFS getstripe -i $f)
19267                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
19268                 local size=$($LFS getstripe -S $f)
19269                 [ $size -eq $((def_stripe_size * 2)) ] ||
19270                         error "$f stripe size $size != $((def_stripe_size * 2))"
19271                 local pool=$($LFS getstripe -p $f)
19272                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
19273         done
19274
19275         # change fs default striping, delete parent default striping, now child
19276         # will stripe from new fs default striping only
19277         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
19278                 error "change $MOUNT default stripe failed"
19279         $LFS setstripe -c 0 $DIR/$tdir ||
19280                 error "delete $tdir default stripe failed"
19281         for i in $(seq 11 20); do
19282                 local f=$DIR/$tdir/$tfile.$i
19283                 touch $f || error "touch $f failed"
19284                 local count=$($LFS getstripe -c $f)
19285                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
19286                 local offset=$($LFS getstripe -i $f)
19287                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
19288                 local size=$($LFS getstripe -S $f)
19289                 [ $size -eq $def_stripe_size ] ||
19290                         error "$f stripe size $size != $def_stripe_size"
19291                 local pool=$($LFS getstripe -p $f)
19292                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
19293         done
19294
19295         unlinkmany $DIR/$tdir/$tfile. 1 20
19296
19297         local f=$DIR/$tdir/$tfile
19298         pool_remove_all_targets $test_pool $f
19299         pool_remove $test_pool $f
19300
19301         if ! combined_mgs_mds ; then
19302                 umount_mgs_client
19303         fi
19304 }
19305 run_test 406 "DNE support fs default striping"
19306
19307 test_407() {
19308         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19309         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19310                 skip "Need MDS version at least 2.8.55"
19311         remote_mds_nodsh && skip "remote MDS with nodsh"
19312
19313         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
19314                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
19315         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
19316                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
19317         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
19318
19319         #define OBD_FAIL_DT_TXN_STOP    0x2019
19320         for idx in $(seq $MDSCOUNT); do
19321                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
19322         done
19323         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
19324         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
19325                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
19326         true
19327 }
19328 run_test 407 "transaction fail should cause operation fail"
19329
19330 test_408() {
19331         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
19332
19333         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
19334         lctl set_param fail_loc=0x8000040a
19335         # let ll_prepare_partial_page() fail
19336         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
19337
19338         rm -f $DIR/$tfile
19339
19340         # create at least 100 unused inodes so that
19341         # shrink_icache_memory(0) should not return 0
19342         touch $DIR/$tfile-{0..100}
19343         rm -f $DIR/$tfile-{0..100}
19344         sync
19345
19346         echo 2 > /proc/sys/vm/drop_caches
19347 }
19348 run_test 408 "drop_caches should not hang due to page leaks"
19349
19350 test_409()
19351 {
19352         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19353
19354         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
19355         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
19356         touch $DIR/$tdir/guard || error "(2) Fail to create"
19357
19358         local PREFIX=$(str_repeat 'A' 128)
19359         echo "Create 1K hard links start at $(date)"
19360         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19361                 error "(3) Fail to hard link"
19362
19363         echo "Links count should be right although linkEA overflow"
19364         stat $DIR/$tdir/guard || error "(4) Fail to stat"
19365         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
19366         [ $linkcount -eq 1001 ] ||
19367                 error "(5) Unexpected hard links count: $linkcount"
19368
19369         echo "List all links start at $(date)"
19370         ls -l $DIR/$tdir/foo > /dev/null ||
19371                 error "(6) Fail to list $DIR/$tdir/foo"
19372
19373         echo "Unlink hard links start at $(date)"
19374         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19375                 error "(7) Fail to unlink"
19376         echo "Unlink hard links finished at $(date)"
19377 }
19378 run_test 409 "Large amount of cross-MDTs hard links on the same file"
19379
19380 test_410()
19381 {
19382         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
19383                 skip "Need client version at least 2.9.59"
19384
19385         # Create a file, and stat it from the kernel
19386         local testfile=$DIR/$tfile
19387         touch $testfile
19388
19389         local run_id=$RANDOM
19390         local my_ino=$(stat --format "%i" $testfile)
19391
19392         # Try to insert the module. This will always fail as the
19393         # module is designed to not be inserted.
19394         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
19395             &> /dev/null
19396
19397         # Anything but success is a test failure
19398         dmesg | grep -q \
19399             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
19400             error "no inode match"
19401 }
19402 run_test 410 "Test inode number returned from kernel thread"
19403
19404 cleanup_test411_cgroup() {
19405         trap 0
19406         rmdir "$1"
19407 }
19408
19409 test_411() {
19410         local cg_basedir=/sys/fs/cgroup/memory
19411         # LU-9966
19412         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
19413                 skip "no setup for cgroup"
19414
19415         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
19416                 error "test file creation failed"
19417         cancel_lru_locks osc
19418
19419         # Create a very small memory cgroup to force a slab allocation error
19420         local cgdir=$cg_basedir/osc_slab_alloc
19421         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
19422         trap "cleanup_test411_cgroup $cgdir" EXIT
19423         echo 2M > $cgdir/memory.kmem.limit_in_bytes
19424         echo 1M > $cgdir/memory.limit_in_bytes
19425
19426         # Should not LBUG, just be killed by oom-killer
19427         # dd will return 0 even allocation failure in some environment.
19428         # So don't check return value
19429         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
19430         cleanup_test411_cgroup $cgdir
19431
19432         return 0
19433 }
19434 run_test 411 "Slab allocation error with cgroup does not LBUG"
19435
19436 test_412() {
19437         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19438         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19439                 skip "Need server version at least 2.10.55"
19440         fi
19441
19442         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
19443                 error "mkdir failed"
19444         $LFS getdirstripe $DIR/$tdir
19445         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19446         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
19447                 error "expect $((MDSCOUT - 1)) get $stripe_index"
19448         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
19449         [ $stripe_count -eq 2 ] ||
19450                 error "expect 2 get $stripe_count"
19451 }
19452 run_test 412 "mkdir on specific MDTs"
19453
19454 test_413() {
19455         [ $MDSCOUNT -lt 2 ] &&
19456                 skip "We need at least 2 MDTs for this test"
19457
19458         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19459                 skip "Need server version at least 2.10.55"
19460         fi
19461
19462         mkdir $DIR/$tdir || error "mkdir failed"
19463
19464         # find MDT that is the most full
19465         local max=$($LFS df | grep MDT |
19466                 awk 'BEGIN { a=0 }
19467                         { sub("%", "", $5)
19468                           if (0+$5 >= a)
19469                           {
19470                                 a = $5
19471                                 b = $6
19472                           }
19473                         }
19474                      END { split(b, c, ":")
19475                            sub("]", "", c[2])
19476                            print c[2]
19477                          }')
19478
19479         for i in $(seq $((MDSCOUNT - 1))); do
19480                 $LFS mkdir -c $i $DIR/$tdir/d$i ||
19481                         error "mkdir d$i failed"
19482                 $LFS getdirstripe $DIR/$tdir/d$i
19483                 local stripe_index=$($LFS getdirstripe -i $DIR/$tdir/d$i)
19484                 [ $stripe_index -ne $max ] ||
19485                         error "don't expect $max"
19486         done
19487 }
19488 run_test 413 "mkdir on less full MDTs"
19489
19490 test_414() {
19491 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
19492         $LCTL set_param fail_loc=0x80000521
19493         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
19494         rm -f $DIR/$tfile
19495 }
19496 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
19497
19498 test_415() {
19499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19500         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
19501                 skip "Need server version at least 2.11.52"
19502
19503         # LU-11102
19504         local total
19505         local setattr_pid
19506         local start_time
19507         local end_time
19508         local duration
19509
19510         total=500
19511         # this test may be slow on ZFS
19512         [ "$mds1_FSTYPE" == "zfs" ] && total=100
19513
19514         # though this test is designed for striped directory, let's test normal
19515         # directory too since lock is always saved as CoS lock.
19516         test_mkdir $DIR/$tdir || error "mkdir $tdir"
19517         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
19518
19519         (
19520                 while true; do
19521                         touch $DIR/$tdir
19522                 done
19523         ) &
19524         setattr_pid=$!
19525
19526         start_time=$(date +%s)
19527         for i in $(seq $total); do
19528                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
19529                         > /dev/null
19530         done
19531         end_time=$(date +%s)
19532         duration=$((end_time - start_time))
19533
19534         kill -9 $setattr_pid
19535
19536         echo "rename $total files took $duration sec"
19537         [ $duration -lt 100 ] || error "rename took $duration sec"
19538 }
19539 run_test 415 "lock revoke is not missing"
19540
19541 test_416() {
19542         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
19543                 skip "Need server version at least 2.11.55"
19544
19545         # define OBD_FAIL_OSD_TXN_START    0x19a
19546         do_facet mds1 lctl set_param fail_loc=0x19a
19547
19548         lfs mkdir -c $MDSCOUNT $DIR/$tdir
19549
19550         true
19551 }
19552 run_test 416 "transaction start failure won't cause system hung"
19553
19554 cleanup_417() {
19555         trap 0
19556         do_nodes $(comma_list $(mdts_nodes)) \
19557                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
19558         do_nodes $(comma_list $(mdts_nodes)) \
19559                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
19560         do_nodes $(comma_list $(mdts_nodes)) \
19561                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
19562 }
19563
19564 test_417() {
19565         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19566         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
19567                 skip "Need MDS version at least 2.11.56"
19568
19569         trap cleanup_417 RETURN EXIT
19570
19571         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
19572         do_nodes $(comma_list $(mdts_nodes)) \
19573                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
19574         $LFS migrate -m 0 $DIR/$tdir.1 &&
19575                 error "migrate dir $tdir.1 should fail"
19576
19577         do_nodes $(comma_list $(mdts_nodes)) \
19578                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
19579         $LFS mkdir -i 1 $DIR/$tdir.2 &&
19580                 error "create remote dir $tdir.2 should fail"
19581
19582         do_nodes $(comma_list $(mdts_nodes)) \
19583                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
19584         $LFS mkdir -c 2 $DIR/$tdir.3 &&
19585                 error "create striped dir $tdir.3 should fail"
19586         true
19587 }
19588 run_test 417 "disable remote dir, striped dir and dir migration"
19589
19590 # Checks that the outputs of df [-i] and lfs df [-i] match
19591 #
19592 # usage: check_lfs_df <blocks | inodes> <mountpoint>
19593 check_lfs_df() {
19594         local dir=$2
19595         local inodes
19596         local df_out
19597         local lfs_df_out
19598         local count
19599         local passed=false
19600
19601         # blocks or inodes
19602         [ "$1" == "blocks" ] && inodes= || inodes="-i"
19603
19604         for count in {1..100}; do
19605                 cancel_lru_locks
19606                 sync; sleep 0.2
19607
19608                 # read the lines of interest
19609                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
19610                         error "df $inodes $dir | tail -n +2 failed"
19611                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
19612                         error "lfs df $inodes $dir | grep summary: failed"
19613
19614                 # skip first substrings of each output as they are different
19615                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
19616                 # compare the two outputs
19617                 passed=true
19618                 for i in {1..5}; do
19619                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
19620                 done
19621                 $passed && break
19622         done
19623
19624         if ! $passed; then
19625                 df -P $inodes $dir
19626                 echo
19627                 lfs df $inodes $dir
19628                 error "df and lfs df $1 output mismatch: "      \
19629                       "df ${inodes}: ${df_out[*]}, "            \
19630                       "lfs df ${inodes}: ${lfs_df_out[*]}"
19631         fi
19632 }
19633
19634 test_418() {
19635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19636
19637         local dir=$DIR/$tdir
19638         local numfiles=$((RANDOM % 4096 + 2))
19639         local numblocks=$((RANDOM % 256 + 1))
19640
19641         wait_delete_completed
19642         test_mkdir $dir
19643
19644         # check block output
19645         check_lfs_df blocks $dir
19646         # check inode output
19647         check_lfs_df inodes $dir
19648
19649         # create a single file and retest
19650         echo "Creating a single file and testing"
19651         createmany -o $dir/$tfile- 1 &>/dev/null ||
19652                 error "creating 1 file in $dir failed"
19653         check_lfs_df blocks $dir
19654         check_lfs_df inodes $dir
19655
19656         # create a random number of files
19657         echo "Creating $((numfiles - 1)) files and testing"
19658         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
19659                 error "creating $((numfiles - 1)) files in $dir failed"
19660
19661         # write a random number of blocks to the first test file
19662         echo "Writing $numblocks 4K blocks and testing"
19663         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
19664                 count=$numblocks &>/dev/null ||
19665                 error "dd to $dir/${tfile}-0 failed"
19666
19667         # retest
19668         check_lfs_df blocks $dir
19669         check_lfs_df inodes $dir
19670
19671         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
19672                 error "unlinking $numfiles files in $dir failed"
19673 }
19674 run_test 418 "df and lfs df outputs match"
19675
19676 prep_801() {
19677         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
19678         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
19679                 skip "Need server version at least 2.9.55"
19680
19681         start_full_debug_logging
19682 }
19683
19684 post_801() {
19685         stop_full_debug_logging
19686 }
19687
19688 barrier_stat() {
19689         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
19690                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
19691                            awk '/The barrier for/ { print $7 }')
19692                 echo $st
19693         else
19694                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
19695                 echo \'$st\'
19696         fi
19697 }
19698
19699 barrier_expired() {
19700         local expired
19701
19702         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
19703                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
19704                           awk '/will be expired/ { print $7 }')
19705         else
19706                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
19707         fi
19708
19709         echo $expired
19710 }
19711
19712 test_801a() {
19713         prep_801
19714
19715         echo "Start barrier_freeze at: $(date)"
19716         #define OBD_FAIL_BARRIER_DELAY          0x2202
19717         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
19718         do_facet mgs $LCTL barrier_freeze $FSNAME 10 &
19719
19720         sleep 2
19721         local b_status=$(barrier_stat)
19722         echo "Got barrier status at: $(date)"
19723         [ "$b_status" = "'freezing_p1'" ] ||
19724                 error "(1) unexpected barrier status $b_status"
19725
19726         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
19727         wait
19728         b_status=$(barrier_stat)
19729         [ "$b_status" = "'frozen'" ] ||
19730                 error "(2) unexpected barrier status $b_status"
19731
19732         local expired=$(barrier_expired)
19733         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
19734         sleep $((expired + 3))
19735
19736         b_status=$(barrier_stat)
19737         [ "$b_status" = "'expired'" ] ||
19738                 error "(3) unexpected barrier status $b_status"
19739
19740         do_facet mgs $LCTL barrier_freeze $FSNAME 10 ||
19741                 error "(4) fail to freeze barrier"
19742
19743         b_status=$(barrier_stat)
19744         [ "$b_status" = "'frozen'" ] ||
19745                 error "(5) unexpected barrier status $b_status"
19746
19747         echo "Start barrier_thaw at: $(date)"
19748         #define OBD_FAIL_BARRIER_DELAY          0x2202
19749         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
19750         do_facet mgs $LCTL barrier_thaw $FSNAME &
19751
19752         sleep 2
19753         b_status=$(barrier_stat)
19754         echo "Got barrier status at: $(date)"
19755         [ "$b_status" = "'thawing'" ] ||
19756                 error "(6) unexpected barrier status $b_status"
19757
19758         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
19759         wait
19760         b_status=$(barrier_stat)
19761         [ "$b_status" = "'thawed'" ] ||
19762                 error "(7) unexpected barrier status $b_status"
19763
19764         #define OBD_FAIL_BARRIER_FAILURE        0x2203
19765         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
19766         do_facet mgs $LCTL barrier_freeze $FSNAME
19767
19768         b_status=$(barrier_stat)
19769         [ "$b_status" = "'failed'" ] ||
19770                 error "(8) unexpected barrier status $b_status"
19771
19772         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19773         do_facet mgs $LCTL barrier_thaw $FSNAME
19774
19775         post_801
19776 }
19777 run_test 801a "write barrier user interfaces and stat machine"
19778
19779 test_801b() {
19780         prep_801
19781
19782         mkdir $DIR/$tdir || error "(1) fail to mkdir"
19783         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
19784         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
19785         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
19786         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
19787
19788         cancel_lru_locks mdc
19789
19790         # 180 seconds should be long enough
19791         do_facet mgs $LCTL barrier_freeze $FSNAME 180
19792
19793         local b_status=$(barrier_stat)
19794         [ "$b_status" = "'frozen'" ] ||
19795                 error "(6) unexpected barrier status $b_status"
19796
19797         mkdir $DIR/$tdir/d0/d10 &
19798         mkdir_pid=$!
19799
19800         touch $DIR/$tdir/d1/f13 &
19801         touch_pid=$!
19802
19803         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
19804         ln_pid=$!
19805
19806         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
19807         mv_pid=$!
19808
19809         rm -f $DIR/$tdir/d4/f12 &
19810         rm_pid=$!
19811
19812         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
19813
19814         # To guarantee taht the 'stat' is not blocked
19815         b_status=$(barrier_stat)
19816         [ "$b_status" = "'frozen'" ] ||
19817                 error "(8) unexpected barrier status $b_status"
19818
19819         # let above commands to run at background
19820         sleep 5
19821
19822         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
19823         ps -p $touch_pid || error "(10) touch should be blocked"
19824         ps -p $ln_pid || error "(11) link should be blocked"
19825         ps -p $mv_pid || error "(12) rename should be blocked"
19826         ps -p $rm_pid || error "(13) unlink should be blocked"
19827
19828         b_status=$(barrier_stat)
19829         [ "$b_status" = "'frozen'" ] ||
19830                 error "(14) unexpected barrier status $b_status"
19831
19832         do_facet mgs $LCTL barrier_thaw $FSNAME
19833         b_status=$(barrier_stat)
19834         [ "$b_status" = "'thawed'" ] ||
19835                 error "(15) unexpected barrier status $b_status"
19836
19837         wait $mkdir_pid || error "(16) mkdir should succeed"
19838         wait $touch_pid || error "(17) touch should succeed"
19839         wait $ln_pid || error "(18) link should succeed"
19840         wait $mv_pid || error "(19) rename should succeed"
19841         wait $rm_pid || error "(20) unlink should succeed"
19842
19843         post_801
19844 }
19845 run_test 801b "modification will be blocked by write barrier"
19846
19847 test_801c() {
19848         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19849
19850         prep_801
19851
19852         stop mds2 || error "(1) Fail to stop mds2"
19853
19854         do_facet mgs $LCTL barrier_freeze $FSNAME 30
19855
19856         local b_status=$(barrier_stat)
19857         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
19858                 do_facet mgs $LCTL barrier_thaw $FSNAME
19859                 error "(2) unexpected barrier status $b_status"
19860         }
19861
19862         do_facet mgs $LCTL barrier_rescan $FSNAME ||
19863                 error "(3) Fail to rescan barrier bitmap"
19864
19865         do_facet mgs $LCTL barrier_freeze $FSNAME 10
19866
19867         b_status=$(barrier_stat)
19868         [ "$b_status" = "'frozen'" ] ||
19869                 error "(4) unexpected barrier status $b_status"
19870
19871         do_facet mgs $LCTL barrier_thaw $FSNAME
19872         b_status=$(barrier_stat)
19873         [ "$b_status" = "'thawed'" ] ||
19874                 error "(5) unexpected barrier status $b_status"
19875
19876         local devname=$(mdsdevname 2)
19877
19878         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
19879
19880         do_facet mgs $LCTL barrier_rescan $FSNAME ||
19881                 error "(7) Fail to rescan barrier bitmap"
19882
19883         post_801
19884 }
19885 run_test 801c "rescan barrier bitmap"
19886
19887 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
19888 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
19889 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
19890
19891 cleanup_802a() {
19892         trap 0
19893
19894         stopall
19895         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
19896         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
19897         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
19898         setupall
19899 }
19900
19901 test_802a() {
19902
19903         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
19904         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
19905                 skip "Need server version at least 2.9.55"
19906
19907         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
19908
19909         mkdir $DIR/$tdir || error "(1) fail to mkdir"
19910
19911         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
19912                 error "(2) Fail to copy"
19913
19914         trap cleanup_802a EXIT
19915
19916         # sync by force before remount as readonly
19917         sync; sync_all_data; sleep 3; sync_all_data
19918
19919         stopall
19920
19921         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
19922         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
19923         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
19924
19925         echo "Mount the server as read only"
19926         setupall server_only || error "(3) Fail to start servers"
19927
19928         echo "Mount client without ro should fail"
19929         mount_client $MOUNT &&
19930                 error "(4) Mount client without 'ro' should fail"
19931
19932         echo "Mount client with ro should succeed"
19933         mount_client $MOUNT ro ||
19934                 error "(5) Mount client with 'ro' should succeed"
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         cleanup_802a
19944 }
19945 run_test 802a "simulate readonly device"
19946
19947 test_802b() {
19948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19949         remote_mds_nodsh && skip "remote MDS with nodsh"
19950
19951         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
19952                 skip "readonly option not available"
19953
19954         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
19955
19956         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
19957                 error "(2) Fail to copy"
19958
19959         # write back all cached data before setting MDT to readonly
19960         cancel_lru_locks
19961         sync_all_data
19962
19963         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
19964         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
19965
19966         echo "Modify should be refused"
19967         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
19968
19969         echo "Read should be allowed"
19970         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
19971                 error "(7) Read should succeed under ro mode"
19972
19973         # disable readonly
19974         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
19975 }
19976 run_test 802b "be able to set MDTs to readonly"
19977
19978 test_803() {
19979         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19980         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
19981                 skip "MDS needs to be newer than 2.10.54"
19982
19983         mkdir -p $DIR/$tdir
19984         # Create some objects on all MDTs to trigger related logs objects
19985         for idx in $(seq $MDSCOUNT); do
19986                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
19987                         $DIR/$tdir/dir${idx} ||
19988                         error "Fail to create $DIR/$tdir/dir${idx}"
19989         done
19990
19991         sync; sleep 3
19992         wait_delete_completed # ensure old test cleanups are finished
19993         echo "before create:"
19994         $LFS df -i $MOUNT
19995         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
19996
19997         for i in {1..10}; do
19998                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
19999                         error "Fail to create $DIR/$tdir/foo$i"
20000         done
20001
20002         sync; sleep 3
20003         echo "after create:"
20004         $LFS df -i $MOUNT
20005         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20006
20007         # allow for an llog to be cleaned up during the test
20008         [ $after_used -ge $((before_used + 10 - 1)) ] ||
20009                 error "before ($before_used) + 10 > after ($after_used)"
20010
20011         for i in {1..10}; do
20012                 rm -rf $DIR/$tdir/foo$i ||
20013                         error "Fail to remove $DIR/$tdir/foo$i"
20014         done
20015
20016         sleep 3 # avoid MDT return cached statfs
20017         wait_delete_completed
20018         echo "after unlink:"
20019         $LFS df -i $MOUNT
20020         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20021
20022         # allow for an llog to be created during the test
20023         [ $after_used -le $((before_used + 1)) ] ||
20024                 error "after ($after_used) > before ($before_used) + 1"
20025 }
20026 run_test 803 "verify agent object for remote object"
20027
20028 test_804() {
20029         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20030         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
20031                 skip "MDS needs to be newer than 2.10.54"
20032         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20033
20034         mkdir -p $DIR/$tdir
20035         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
20036                 error "Fail to create $DIR/$tdir/dir0"
20037
20038         local fid=$($LFS path2fid $DIR/$tdir/dir0)
20039         local dev=$(mdsdevname 2)
20040
20041         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20042                 grep ${fid} || error "NOT found agent entry for dir0"
20043
20044         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
20045                 error "Fail to create $DIR/$tdir/dir1"
20046
20047         touch $DIR/$tdir/dir1/foo0 ||
20048                 error "Fail to create $DIR/$tdir/dir1/foo0"
20049         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
20050         local rc=0
20051
20052         for idx in $(seq $MDSCOUNT); do
20053                 dev=$(mdsdevname $idx)
20054                 do_facet mds${idx} \
20055                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20056                         grep ${fid} && rc=$idx
20057         done
20058
20059         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
20060                 error "Fail to rename foo0 to foo1"
20061         if [ $rc -eq 0 ]; then
20062                 for idx in $(seq $MDSCOUNT); do
20063                         dev=$(mdsdevname $idx)
20064                         do_facet mds${idx} \
20065                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20066                         grep ${fid} && rc=$idx
20067                 done
20068         fi
20069
20070         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
20071                 error "Fail to rename foo1 to foo2"
20072         if [ $rc -eq 0 ]; then
20073                 for idx in $(seq $MDSCOUNT); do
20074                         dev=$(mdsdevname $idx)
20075                         do_facet mds${idx} \
20076                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20077                         grep ${fid} && rc=$idx
20078                 done
20079         fi
20080
20081         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
20082
20083         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
20084                 error "Fail to link to $DIR/$tdir/dir1/foo2"
20085         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
20086                 error "Fail to rename foo2 to foo0"
20087         unlink $DIR/$tdir/dir1/foo0 ||
20088                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
20089         rm -rf $DIR/$tdir/dir0 ||
20090                 error "Fail to rm $DIR/$tdir/dir0"
20091
20092         for idx in $(seq $MDSCOUNT); do
20093                 dev=$(mdsdevname $idx)
20094                 rc=0
20095
20096                 stop mds${idx}
20097                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
20098                         rc=$?
20099                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
20100                         error "mount mds$idx failed"
20101                 df $MOUNT > /dev/null 2>&1
20102
20103                 # e2fsck should not return error
20104                 [ $rc -eq 0 ] ||
20105                         error "e2fsck detected error on MDT${idx}: rc=$rc"
20106         done
20107 }
20108 run_test 804 "verify agent entry for remote entry"
20109
20110 cleanup_805() {
20111         do_facet $SINGLEMDS zfs set quota=$old $fsset
20112         unlinkmany $DIR/$tdir/f- 1000000
20113         trap 0
20114 }
20115
20116 test_805() {
20117         local zfs_version=$(do_node $SINGLEMDS cat /sys/module/zfs/version)
20118         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
20119         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
20120                 skip "netfree not implemented before 0.7"
20121         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
20122                 skip "Need MDS version at least 2.10.57"
20123
20124         local fsset
20125         local freekb
20126         local usedkb
20127         local old
20128         local quota
20129         local pref="osd-zfs.lustre-MDT0000."
20130
20131         # limit available space on MDS dataset to meet nospace issue
20132         # quickly. then ZFS 0.7.2 can use reserved space if asked
20133         # properly (using netfree flag in osd_declare_destroy()
20134         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
20135         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
20136                 gawk '{print $3}')
20137         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
20138         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
20139         let "usedkb=usedkb-freekb"
20140         let "freekb=freekb/2"
20141         if let "freekb > 5000"; then
20142                 let "freekb=5000"
20143         fi
20144         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
20145         trap cleanup_805 EXIT
20146         mkdir $DIR/$tdir
20147         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
20148         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
20149         rm -rf $DIR/$tdir || error "not able to remove"
20150         do_facet $SINGLEMDS zfs set quota=$old $fsset
20151         trap 0
20152 }
20153 run_test 805 "ZFS can remove from full fs"
20154
20155 # Size-on-MDS test
20156 check_lsom_data()
20157 {
20158         local file=$1
20159         local size=$($LFS getsom -s $file)
20160         local expect=$(stat -c %s $file)
20161
20162         [[ $size == $expect ]] ||
20163                 error "$file expected size: $expect, got: $size"
20164
20165         local blocks=$($LFS getsom -b $file)
20166         expect=$(stat -c %b $file)
20167         [[ $blocks == $expect ]] ||
20168                 error "$file expected blocks: $expect, got: $blocks"
20169 }
20170
20171 check_lsom_size()
20172 {
20173         local size=$($LFS getsom -s $1)
20174         local expect=$2
20175
20176         [[ $size == $expect ]] ||
20177                 error "$file expected size: $expect, got: $size"
20178 }
20179
20180 test_806() {
20181         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20182                 skip "Need MDS version at least 2.11.52"
20183
20184         local bs=1048576
20185
20186         touch $DIR/$tfile || error "touch $tfile failed"
20187
20188         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20189         save_lustre_params client "llite.*.xattr_cache" > $save
20190         lctl set_param llite.*.xattr_cache=0
20191         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20192
20193         # single-threaded write
20194         echo "Test SOM for single-threaded write"
20195         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
20196                 error "write $tfile failed"
20197         check_lsom_size $DIR/$tfile $bs
20198
20199         local num=32
20200         local size=$(($num * $bs))
20201         local offset=0
20202         local i
20203
20204         echo "Test SOM for single client multi-threaded($num) write"
20205         $TRUNCATE $DIR/$tfile 0
20206         for ((i = 0; i < $num; i++)); do
20207                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20208                 local pids[$i]=$!
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 $size
20215
20216         $TRUNCATE $DIR/$tfile 0
20217         for ((i = 0; i < $num; i++)); do
20218                 offset=$((offset - $bs))
20219                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20220                 local pids[$i]=$!
20221         done
20222         for (( i=0; i < $num; i++ )); do
20223                 wait ${pids[$i]}
20224         done
20225         check_lsom_size $DIR/$tfile $size
20226
20227         # multi-client wirtes
20228         num=$(get_node_count ${CLIENTS//,/ })
20229         size=$(($num * $bs))
20230         offset=0
20231         i=0
20232
20233         echo "Test SOM for multi-client ($num) writes"
20234         $TRUNCATE $DIR/$tfile 0
20235         for client in ${CLIENTS//,/ }; do
20236                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20237                 local pids[$i]=$!
20238                 i=$((i + 1))
20239                 offset=$((offset + $bs))
20240         done
20241         for (( i=0; i < $num; i++ )); do
20242                 wait ${pids[$i]}
20243         done
20244         check_lsom_size $DIR/$tfile $offset
20245
20246         i=0
20247         $TRUNCATE $DIR/$tfile 0
20248         for client in ${CLIENTS//,/ }; do
20249                 offset=$((offset - $bs))
20250                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20251                 local pids[$i]=$!
20252                 i=$((i + 1))
20253         done
20254         for (( i=0; i < $num; i++ )); do
20255                 wait ${pids[$i]}
20256         done
20257         check_lsom_size $DIR/$tfile $size
20258
20259         # verify truncate
20260         echo "Test SOM for truncate"
20261         $TRUNCATE $DIR/$tfile 1048576
20262         check_lsom_size $DIR/$tfile 1048576
20263         $TRUNCATE $DIR/$tfile 1234
20264         check_lsom_size $DIR/$tfile 1234
20265
20266         # verify SOM blocks count
20267         echo "Verify SOM block count"
20268         $TRUNCATE $DIR/$tfile 0
20269         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
20270                 error "failed to write file $tfile"
20271         check_lsom_data $DIR/$tfile
20272 }
20273 run_test 806 "Verify Lazy Size on MDS"
20274
20275 test_807() {
20276         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
20277         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20278                 skip "Need MDS version at least 2.11.52"
20279
20280         # Registration step
20281         changelog_register || error "changelog_register failed"
20282         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
20283         changelog_users $SINGLEMDS | grep -q $cl_user ||
20284                 error "User $cl_user not found in changelog_users"
20285
20286         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20287         save_lustre_params client "llite.*.xattr_cache" > $save
20288         lctl set_param llite.*.xattr_cache=0
20289         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20290
20291         rm -rf $DIR/$tdir || error "rm $tdir failed"
20292         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
20293         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
20294         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
20295         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
20296                 error "truncate $tdir/trunc failed"
20297
20298         local bs=1048576
20299         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
20300                 error "write $tfile failed"
20301
20302         # multi-client wirtes
20303         local num=$(get_node_count ${CLIENTS//,/ })
20304         local offset=0
20305         local i=0
20306
20307         echo "Test SOM for multi-client ($num) writes"
20308         touch $DIR/$tfile || error "touch $tfile failed"
20309         $TRUNCATE $DIR/$tfile 0
20310         for client in ${CLIENTS//,/ }; do
20311                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20312                 local pids[$i]=$!
20313                 i=$((i + 1))
20314                 offset=$((offset + $bs))
20315         done
20316         for (( i=0; i < $num; i++ )); do
20317                 wait ${pids[$i]}
20318         done
20319
20320         sleep 5
20321         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
20322         check_lsom_data $DIR/$tdir/trunc
20323         check_lsom_data $DIR/$tdir/single_dd
20324         check_lsom_data $DIR/$tfile
20325
20326         rm -rf $DIR/$tdir
20327         # Deregistration step
20328         changelog_deregister || error "changelog_deregister failed"
20329 }
20330 run_test 807 "verify LSOM syncing tool"
20331
20332 check_som_nologged()
20333 {
20334         local lines=$($LFS changelog $FSNAME-MDT0000 |
20335                 grep 'x=trusted.som' | wc -l)
20336         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
20337 }
20338
20339 test_808() {
20340         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
20341                 skip "Need MDS version at least 2.11.55"
20342
20343         # Registration step
20344         changelog_register || error "changelog_register failed"
20345
20346         touch $DIR/$tfile || error "touch $tfile failed"
20347         check_som_nologged
20348
20349         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
20350                 error "write $tfile failed"
20351         check_som_nologged
20352
20353         $TRUNCATE $DIR/$tfile 1234
20354         check_som_nologged
20355
20356         $TRUNCATE $DIR/$tfile 1048576
20357         check_som_nologged
20358
20359         # Deregistration step
20360         changelog_deregister || error "changelog_deregister failed"
20361 }
20362 run_test 808 "Check trusted.som xattr not logged in Changelogs"
20363
20364 check_som_nodata()
20365 {
20366         $LFS getsom $1
20367         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
20368 }
20369
20370 test_809() {
20371         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20372                 skip "Need MDS version at least 2.11.56"
20373
20374         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
20375                 error "failed to create DoM-only file $DIR/$tfile"
20376         touch $DIR/$tfile || error "touch $tfile failed"
20377         check_som_nodata $DIR/$tfile
20378
20379         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
20380                 error "write $tfile failed"
20381         check_som_nodata $DIR/$tfile
20382
20383         $TRUNCATE $DIR/$tfile 1234
20384         check_som_nodata $DIR/$tfile
20385
20386         $TRUNCATE $DIR/$tfile 4097
20387         check_som_nodata $DIR/$file
20388 }
20389 run_test 809 "Verify no SOM xattr store for DoM-only files"
20390
20391 test_810() {
20392         local ORIG
20393         local CSUM
20394
20395         # t10 seem to dislike partial pages
20396         lctl set_param osc.*.checksum_type=adler
20397         lctl set_param fail_loc=0x411
20398         dd if=/dev/urandom of=$DIR/$tfile bs=10240 count=2
20399         ORIG=$(md5sum $DIR/$tfile)
20400         lctl set_param ldlm.namespaces.*osc*.lru_size=clear
20401         CSUM=$(md5sum $DIR/$tfile)
20402         set_checksum_type adler
20403         if [ "$ORIG" != "$CSUM" ]; then
20404                 error "$ORIG != $CSUM"
20405         fi
20406 }
20407 run_test 810 "partial page writes on ZFS (LU-11663)"
20408
20409 test_811() {
20410         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
20411                 skip "Need MDS version at least 2.11.56"
20412
20413         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
20414         do_facet mds1 $LCTL set_param fail_loc=0x165
20415         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
20416
20417         stop mds1
20418         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20419
20420         sleep 5
20421         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
20422                 error "MDD orphan cleanup thread not quit"
20423 }
20424 run_test 811 "orphan name stub can be cleaned up in startup"
20425
20426 test_812() {
20427         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
20428                 skip "OST < 2.12.51 doesn't support this fail_loc"
20429
20430         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20431         # ensure ost1 is connected
20432         stat $DIR/$tfile >/dev/null || error "can't stat"
20433         wait_osc_import_state client ost1 FULL
20434         # no locks, no reqs to let the connection idle
20435         cancel_lru_locks osc
20436
20437         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
20438 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
20439         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
20440         wait_osc_import_state client ost1 CONNECTING
20441         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
20442
20443         stat $DIR/$tfile >/dev/null || error "can't stat file"
20444 }
20445 run_test 812 "do not drop reqs generated when imp is going to idle (LU-11951)"
20446
20447 test_813() {
20448         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
20449         [ -z "$file_heat_sav" ] && skip "no file heat support"
20450
20451         local readsample
20452         local writesample
20453         local readbyte
20454         local writebyte
20455         local readsample1
20456         local writesample1
20457         local readbyte1
20458         local writebyte1
20459
20460         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
20461         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
20462
20463         $LCTL set_param -n llite.*.file_heat=1
20464         echo "Turn on file heat"
20465         echo "Period second: $period_second, Decay percentage: $decay_pct"
20466
20467         echo "QQQQ" > $DIR/$tfile
20468         echo "QQQQ" > $DIR/$tfile
20469         echo "QQQQ" > $DIR/$tfile
20470         cat $DIR/$tfile > /dev/null
20471         cat $DIR/$tfile > /dev/null
20472         cat $DIR/$tfile > /dev/null
20473         cat $DIR/$tfile > /dev/null
20474
20475         local out=$($LFS heat_get $DIR/$tfile)
20476
20477         $LFS heat_get $DIR/$tfile
20478         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20479         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20480         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20481         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20482
20483         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
20484         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
20485         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
20486         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
20487
20488         sleep $((period_second + 3))
20489         echo "Sleep $((period_second + 3)) seconds..."
20490         # The recursion formula to calculate the heat of the file f is as
20491         # follow:
20492         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
20493         # Where Hi is the heat value in the period between time points i*I and
20494         # (i+1)*I; Ci is the access count in the period; the symbol P refers
20495         # to the weight of Ci.
20496         out=$($LFS heat_get $DIR/$tfile)
20497         $LFS heat_get $DIR/$tfile
20498         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20499         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20500         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20501         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20502
20503         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
20504                 error "read sample ($readsample) is wrong"
20505         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
20506                 error "write sample ($writesample) is wrong"
20507         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
20508                 error "read bytes ($readbyte) is wrong"
20509         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
20510                 error "write bytes ($writebyte) is wrong"
20511
20512         echo "QQQQ" > $DIR/$tfile
20513         echo "QQQQ" > $DIR/$tfile
20514         echo "QQQQ" > $DIR/$tfile
20515         cat $DIR/$tfile > /dev/null
20516         cat $DIR/$tfile > /dev/null
20517         cat $DIR/$tfile > /dev/null
20518         cat $DIR/$tfile > /dev/null
20519
20520         sleep $((period_second + 3))
20521         echo "Sleep $((period_second + 3)) seconds..."
20522
20523         out=$($LFS heat_get $DIR/$tfile)
20524         $LFS heat_get $DIR/$tfile
20525         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20526         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20527         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20528         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20529
20530         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
20531                 4 * $decay_pct) / 100") -eq 1 ] ||
20532                 error "read sample ($readsample1) is wrong"
20533         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
20534                 3 * $decay_pct) / 100") -eq 1 ] ||
20535                 error "write sample ($writesample1) is wrong"
20536         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
20537                 20 * $decay_pct) / 100") -eq 1 ] ||
20538                 error "read bytes ($readbyte1) is wrong"
20539         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
20540                 15 * $decay_pct) / 100") -eq 1 ] ||
20541                 error "write bytes ($writebyte1) is wrong"
20542
20543         echo "Turn off file heat for the file $DIR/$tfile"
20544         $LFS heat_set -o $DIR/$tfile
20545
20546         echo "QQQQ" > $DIR/$tfile
20547         echo "QQQQ" > $DIR/$tfile
20548         echo "QQQQ" > $DIR/$tfile
20549         cat $DIR/$tfile > /dev/null
20550         cat $DIR/$tfile > /dev/null
20551         cat $DIR/$tfile > /dev/null
20552         cat $DIR/$tfile > /dev/null
20553
20554         out=$($LFS heat_get $DIR/$tfile)
20555         $LFS heat_get $DIR/$tfile
20556         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20557         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20558         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20559         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20560
20561         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
20562         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
20563         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
20564         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
20565
20566         echo "Trun on file heat for the file $DIR/$tfile"
20567         $LFS heat_set -O $DIR/$tfile
20568
20569         echo "QQQQ" > $DIR/$tfile
20570         echo "QQQQ" > $DIR/$tfile
20571         echo "QQQQ" > $DIR/$tfile
20572         cat $DIR/$tfile > /dev/null
20573         cat $DIR/$tfile > /dev/null
20574         cat $DIR/$tfile > /dev/null
20575         cat $DIR/$tfile > /dev/null
20576
20577         out=$($LFS heat_get $DIR/$tfile)
20578         $LFS heat_get $DIR/$tfile
20579         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20580         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20581         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20582         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20583
20584         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
20585         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
20586         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
20587         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
20588
20589         $LFS heat_set -c $DIR/$tfile
20590         $LCTL set_param -n llite.*.file_heat=0
20591         echo "Turn off file heat support for the Lustre filesystem"
20592
20593         echo "QQQQ" > $DIR/$tfile
20594         echo "QQQQ" > $DIR/$tfile
20595         echo "QQQQ" > $DIR/$tfile
20596         cat $DIR/$tfile > /dev/null
20597         cat $DIR/$tfile > /dev/null
20598         cat $DIR/$tfile > /dev/null
20599         cat $DIR/$tfile > /dev/null
20600
20601         out=$($LFS heat_get $DIR/$tfile)
20602         $LFS heat_get $DIR/$tfile
20603         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20604         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20605         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20606         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20607
20608         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
20609         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
20610         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
20611         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
20612
20613         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
20614         rm -f $DIR/$tfile
20615 }
20616 run_test 813 "File heat verfication"
20617
20618 #
20619 # tests that do cleanup/setup should be run at the end
20620 #
20621
20622 test_900() {
20623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20624         local ls
20625
20626         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
20627         $LCTL set_param fail_loc=0x903
20628
20629         cancel_lru_locks MGC
20630
20631         FAIL_ON_ERROR=true cleanup
20632         FAIL_ON_ERROR=true setup
20633 }
20634 run_test 900 "umount should not race with any mgc requeue thread"
20635
20636 complete $SECONDS
20637 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
20638 check_and_cleanup_lustre
20639 if [ "$I_MOUNTED" != "yes" ]; then
20640         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
20641 fi
20642 exit_status