Whamcloud - gitweb
e351eee422037f2ed32783313bda6c18a1a8e0f7
[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_27ga() {
1577         test_mkdir $DIR/$tdir
1578         touch $DIR/$tdir/$tfile || error "touch failed"
1579         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1580         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1581         local rc=$?
1582         (( rc == 2 )) || error "getstripe did not return ENOENT"
1583 }
1584 run_test 27ga "$LFS getstripe with missing file (should return error)"
1585
1586 test_27i() {
1587         test_mkdir $DIR/$tdir
1588         touch $DIR/$tdir/$tfile || error "touch failed"
1589         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1590                 error "missing objects"
1591 }
1592 run_test 27i "$LFS getstripe with some objects"
1593
1594 test_27j() {
1595         test_mkdir $DIR/$tdir
1596         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1597                 error "setstripe failed" || true
1598 }
1599 run_test 27j "setstripe with bad stripe offset (should return error)"
1600
1601 test_27k() { # bug 2844
1602         test_mkdir $DIR/$tdir
1603         local file=$DIR/$tdir/$tfile
1604         local ll_max_blksize=$((4 * 1024 * 1024))
1605         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1606         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1607         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1608         dd if=/dev/zero of=$file bs=4k count=1
1609         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1610         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1611 }
1612 run_test 27k "limit i_blksize for broken user apps"
1613
1614 test_27l() {
1615         mcreate $DIR/$tfile || error "creating file"
1616         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1617                 error "setstripe should have failed" || true
1618 }
1619 run_test 27l "check setstripe permissions (should return error)"
1620
1621 test_27m() {
1622         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1623
1624         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1625                 skip_env "multiple clients -- skipping"
1626
1627         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1628                    head -n1)
1629         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1630                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1631         fi
1632         trap simple_cleanup_common EXIT
1633         test_mkdir $DIR/$tdir
1634         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1635         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1636                 error "dd should fill OST0"
1637         i=2
1638         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1639                 i=$((i + 1))
1640                 [ $i -gt 256 ] && break
1641         done
1642         i=$((i + 1))
1643         touch $DIR/$tdir/$tfile.$i
1644         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1645             awk '{print $1}'| grep -w "0") ] &&
1646                 error "OST0 was full but new created file still use it"
1647         i=$((i + 1))
1648         touch $DIR/$tdir/$tfile.$i
1649         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1650             awk '{print $1}'| grep -w "0") ] &&
1651                 error "OST0 was full but new created file still use it"
1652         simple_cleanup_common
1653 }
1654 run_test 27m "create file while OST0 was full"
1655
1656 sleep_maxage() {
1657         local delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1658                       awk '{ print $1 * 2; exit; }')
1659         sleep $delay
1660 }
1661
1662 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1663 # if the OST isn't full anymore.
1664 reset_enospc() {
1665         local OSTIDX=${1:-""}
1666
1667         local list=$(comma_list $(osts_nodes))
1668         [ "$OSTIDX" ] && list=$(facet_host ost$((OSTIDX + 1)))
1669
1670         do_nodes $list lctl set_param fail_loc=0
1671         sync    # initiate all OST_DESTROYs from MDS to OST
1672         sleep_maxage
1673 }
1674
1675 exhaust_precreations() {
1676         local OSTIDX=$1
1677         local FAILLOC=$2
1678         local FAILIDX=${3:-$OSTIDX}
1679         local ofacet=ost$((OSTIDX + 1))
1680
1681         test_mkdir -p -c1 $DIR/$tdir
1682         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1683         local mfacet=mds$((mdtidx + 1))
1684         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1685
1686         local OST=$(ostname_from_index $OSTIDX)
1687
1688         # on the mdt's osc
1689         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1690         local last_id=$(do_facet $mfacet lctl get_param -n \
1691                         osc.$mdtosc_proc1.prealloc_last_id)
1692         local next_id=$(do_facet $mfacet lctl get_param -n \
1693                         osc.$mdtosc_proc1.prealloc_next_id)
1694
1695         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1696         do_facet $mfacet lctl get_param osc.$mdtosc_proc2.prealloc*
1697
1698         test_mkdir -p $DIR/$tdir/${OST}
1699         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1700 #define OBD_FAIL_OST_ENOSPC              0x215
1701         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1702         echo "Creating to objid $last_id on ost $OST..."
1703         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1704         do_facet $mfacet lctl get_param osc.$mdtosc_proc2.prealloc*
1705         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1706         sleep_maxage
1707 }
1708
1709 exhaust_all_precreations() {
1710         local i
1711         for (( i=0; i < OSTCOUNT; i++ )) ; do
1712                 exhaust_precreations $i $1 -1
1713         done
1714 }
1715
1716 test_27n() {
1717         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1719         remote_mds_nodsh && skip "remote MDS with nodsh"
1720         remote_ost_nodsh && skip "remote OST with nodsh"
1721
1722         reset_enospc
1723         rm -f $DIR/$tdir/$tfile
1724         exhaust_precreations 0 0x80000215
1725         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1726         touch $DIR/$tdir/$tfile || error "touch failed"
1727         $LFS getstripe $DIR/$tdir/$tfile
1728         reset_enospc
1729 }
1730 run_test 27n "create file with some full OSTs"
1731
1732 test_27o() {
1733         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1735         remote_mds_nodsh && skip "remote MDS with nodsh"
1736         remote_ost_nodsh && skip "remote OST with nodsh"
1737
1738         reset_enospc
1739         rm -f $DIR/$tdir/$tfile
1740         exhaust_all_precreations 0x215
1741
1742         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1743
1744         reset_enospc
1745         rm -rf $DIR/$tdir/*
1746 }
1747 run_test 27o "create file with all full OSTs (should error)"
1748
1749 test_27p() {
1750         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1752         remote_mds_nodsh && skip "remote MDS with nodsh"
1753         remote_ost_nodsh && skip "remote OST with nodsh"
1754
1755         reset_enospc
1756         rm -f $DIR/$tdir/$tfile
1757         test_mkdir $DIR/$tdir
1758
1759         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1760         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1761         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1762
1763         exhaust_precreations 0 0x80000215
1764         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1765         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1766         $LFS getstripe $DIR/$tdir/$tfile
1767
1768         reset_enospc
1769 }
1770 run_test 27p "append to a truncated file with some full OSTs"
1771
1772 test_27q() {
1773         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1775         remote_mds_nodsh && skip "remote MDS with nodsh"
1776         remote_ost_nodsh && skip "remote OST with nodsh"
1777
1778         reset_enospc
1779         rm -f $DIR/$tdir/$tfile
1780
1781         test_mkdir $DIR/$tdir
1782         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1783         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1784                 error "truncate $DIR/$tdir/$tfile failed"
1785         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1786
1787         exhaust_all_precreations 0x215
1788
1789         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1790         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1791
1792         reset_enospc
1793 }
1794 run_test 27q "append to truncated file with all OSTs full (should error)"
1795
1796 test_27r() {
1797         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1799         remote_mds_nodsh && skip "remote MDS with nodsh"
1800         remote_ost_nodsh && skip "remote OST with nodsh"
1801
1802         reset_enospc
1803         rm -f $DIR/$tdir/$tfile
1804         exhaust_precreations 0 0x80000215
1805
1806         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1807
1808         reset_enospc
1809 }
1810 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1811
1812 test_27s() { # bug 10725
1813         test_mkdir $DIR/$tdir
1814         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1815         local stripe_count=0
1816         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1817         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1818                 error "stripe width >= 2^32 succeeded" || true
1819
1820 }
1821 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1822
1823 test_27t() { # bug 10864
1824         WDIR=$(pwd)
1825         WLFS=$(which lfs)
1826         cd $DIR
1827         touch $tfile
1828         $WLFS getstripe $tfile
1829         cd $WDIR
1830 }
1831 run_test 27t "check that utils parse path correctly"
1832
1833 test_27u() { # bug 4900
1834         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1835         remote_mds_nodsh && skip "remote MDS with nodsh"
1836
1837         local index
1838         local list=$(comma_list $(mdts_nodes))
1839
1840 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1841         do_nodes $list $LCTL set_param fail_loc=0x139
1842         test_mkdir -p $DIR/$tdir
1843         trap simple_cleanup_common EXIT
1844         createmany -o $DIR/$tdir/t- 1000
1845         do_nodes $list $LCTL set_param fail_loc=0
1846
1847         TLOG=$TMP/$tfile.getstripe
1848         $LFS getstripe $DIR/$tdir > $TLOG
1849         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1850         unlinkmany $DIR/$tdir/t- 1000
1851         trap 0
1852         [[ $OBJS -gt 0 ]] &&
1853                 error "$OBJS objects created on OST-0. See $TLOG" ||
1854                 rm -f $TLOG
1855 }
1856 run_test 27u "skip object creation on OSC w/o objects"
1857
1858 test_27v() { # bug 4900
1859         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1861         remote_mds_nodsh && skip "remote MDS with nodsh"
1862         remote_ost_nodsh && skip "remote OST with nodsh"
1863
1864         exhaust_all_precreations 0x215
1865         reset_enospc
1866
1867         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1868
1869         touch $DIR/$tdir/$tfile
1870         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
1871         # all except ost1
1872         for (( i=1; i < OSTCOUNT; i++ )); do
1873                 do_facet ost$i lctl set_param fail_loc=0x705
1874         done
1875         local START=`date +%s`
1876         createmany -o $DIR/$tdir/$tfile 32
1877
1878         local FINISH=`date +%s`
1879         local TIMEOUT=`lctl get_param -n timeout`
1880         local PROCESS=$((FINISH - START))
1881         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
1882                error "$FINISH - $START >= $TIMEOUT / 2"
1883         sleep $((TIMEOUT / 2 - PROCESS))
1884         reset_enospc
1885 }
1886 run_test 27v "skip object creation on slow OST"
1887
1888 test_27w() { # bug 10997
1889         test_mkdir $DIR/$tdir
1890         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
1891         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
1892                 error "stripe size $size != 65536" || true
1893         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
1894                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
1895 }
1896 run_test 27w "check $LFS setstripe -S and getstrip -d options"
1897
1898 test_27wa() {
1899         [[ $OSTCOUNT -lt 2 ]] &&
1900                 skip_env "skipping multiple stripe count/offset test"
1901
1902         test_mkdir $DIR/$tdir
1903         for i in $(seq 1 $OSTCOUNT); do
1904                 offset=$((i - 1))
1905                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
1906                         error "setstripe -c $i -i $offset failed"
1907                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
1908                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
1909                 [ $count -ne $i ] && error "stripe count $count != $i" || true
1910                 [ $index -ne $offset ] &&
1911                         error "stripe offset $index != $offset" || true
1912         done
1913 }
1914 run_test 27wa "check $LFS setstripe -c -i options"
1915
1916 test_27x() {
1917         remote_ost_nodsh && skip "remote OST with nodsh"
1918         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1920
1921         OFFSET=$(($OSTCOUNT - 1))
1922         OSTIDX=0
1923         local OST=$(ostname_from_index $OSTIDX)
1924
1925         test_mkdir $DIR/$tdir
1926         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
1927         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
1928         sleep_maxage
1929         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
1930         for i in $(seq 0 $OFFSET); do
1931                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
1932                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
1933                 error "OST0 was degraded but new created file still use it"
1934         done
1935         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
1936 }
1937 run_test 27x "create files while OST0 is degraded"
1938
1939 test_27y() {
1940         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1941         remote_mds_nodsh && skip "remote MDS with nodsh"
1942         remote_ost_nodsh && skip "remote OST with nodsh"
1943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1944
1945         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
1946         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
1947                 osc.$mdtosc.prealloc_last_id)
1948         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
1949                 osc.$mdtosc.prealloc_next_id)
1950         local fcount=$((last_id - next_id))
1951         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
1952         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
1953
1954         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
1955                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
1956         local OST_DEACTIVE_IDX=-1
1957         local OSC
1958         local OSTIDX
1959         local OST
1960
1961         for OSC in $MDS_OSCS; do
1962                 OST=$(osc_to_ost $OSC)
1963                 OSTIDX=$(index_from_ostuuid $OST)
1964                 if [ $OST_DEACTIVE_IDX == -1 ]; then
1965                         OST_DEACTIVE_IDX=$OSTIDX
1966                 fi
1967                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
1968                         echo $OSC "is Deactivated:"
1969                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
1970                 fi
1971         done
1972
1973         OSTIDX=$(index_from_ostuuid $OST)
1974         test_mkdir $DIR/$tdir
1975         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
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 degraded:"
1982                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
1983                                                 obdfilter.$OST.degraded=1
1984                 fi
1985         done
1986
1987         sleep_maxage
1988         createmany -o $DIR/$tdir/$tfile $fcount
1989
1990         for OSC in $MDS_OSCS; do
1991                 OST=$(osc_to_ost $OSC)
1992                 OSTIDX=$(index_from_ostuuid $OST)
1993                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
1994                         echo $OST "is recovered from degraded:"
1995                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
1996                                                 obdfilter.$OST.degraded=0
1997                 else
1998                         do_facet $SINGLEMDS lctl --device %$OSC activate
1999                 fi
2000         done
2001
2002         # all osp devices get activated, hence -1 stripe count restored
2003         local stripe_count=0
2004
2005         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2006         # devices get activated.
2007         sleep_maxage
2008         $LFS setstripe -c -1 $DIR/$tfile
2009         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2010         rm -f $DIR/$tfile
2011         [ $stripe_count -ne $OSTCOUNT ] &&
2012                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2013         return 0
2014 }
2015 run_test 27y "create files while OST0 is degraded and the rest inactive"
2016
2017 check_seq_oid()
2018 {
2019         log "check file $1"
2020
2021         lmm_count=$($LFS getstripe -c $1)
2022         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2023         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2024
2025         local old_ifs="$IFS"
2026         IFS=$'[:]'
2027         fid=($($LFS path2fid $1))
2028         IFS="$old_ifs"
2029
2030         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2031         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2032
2033         # compare lmm_seq and lu_fid->f_seq
2034         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2035         # compare lmm_object_id and lu_fid->oid
2036         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2037
2038         # check the trusted.fid attribute of the OST objects of the file
2039         local have_obdidx=false
2040         local stripe_nr=0
2041         $LFS getstripe $1 | while read obdidx oid hex seq; do
2042                 # skip lines up to and including "obdidx"
2043                 [ -z "$obdidx" ] && break
2044                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2045                 $have_obdidx || continue
2046
2047                 local ost=$((obdidx + 1))
2048                 local dev=$(ostdevname $ost)
2049                 local oid_hex
2050
2051                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2052
2053                 seq=$(echo $seq | sed -e "s/^0x//g")
2054                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2055                         oid_hex=$(echo $oid)
2056                 else
2057                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2058                 fi
2059                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2060
2061                 local ff=""
2062                 #
2063                 # Don't unmount/remount the OSTs if we don't need to do that.
2064                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2065                 # update too, until that use mount/ll_decode_filter_fid/mount.
2066                 # Re-enable when debugfs will understand new filter_fid.
2067                 #
2068                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2069                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2070                                 $dev 2>/dev/null" | grep "parent=")
2071                 fi
2072                 if [ -z "$ff" ]; then
2073                         stop ost$ost
2074                         mount_fstype ost$ost
2075                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2076                                 $(facet_mntpt ost$ost)/$obj_file)
2077                         unmount_fstype ost$ost
2078                         start ost$ost $dev $OST_MOUNT_OPTS
2079                         clients_up
2080                 fi
2081
2082                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2083
2084                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2085
2086                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2087                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2088                 #
2089                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2090                 #       stripe_size=1048576 component_id=1 component_start=0 \
2091                 #       component_end=33554432
2092                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2093                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2094                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2095                 local ff_pstripe
2096                 if grep -q 'stripe=' <<<$ff; then
2097                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2098                 else
2099                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2100                         # into f_ver in this case.  See comment on ff_parent.
2101                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2102                 fi
2103
2104                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2105                 [ $ff_pseq = $lmm_seq ] ||
2106                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2107                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2108                 [ $ff_poid = $lmm_oid ] ||
2109                         error "FF parent OID $ff_poid != $lmm_oid"
2110                 (($ff_pstripe == $stripe_nr)) ||
2111                         error "FF stripe $ff_pstripe != $stripe_nr"
2112
2113                 stripe_nr=$((stripe_nr + 1))
2114                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2115                         continue
2116                 if grep -q 'stripe_count=' <<<$ff; then
2117                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2118                                             -e 's/ .*//' <<<$ff)
2119                         [ $lmm_count = $ff_scnt ] ||
2120                                 error "FF stripe count $lmm_count != $ff_scnt"
2121                 fi
2122         done
2123 }
2124
2125 test_27z() {
2126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2127         remote_ost_nodsh && skip "remote OST with nodsh"
2128
2129         test_mkdir $DIR/$tdir
2130         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2131                 { error "setstripe -c -1 failed"; return 1; }
2132         # We need to send a write to every object to get parent FID info set.
2133         # This _should_ also work for setattr, but does not currently.
2134         # touch $DIR/$tdir/$tfile-1 ||
2135         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2136                 { error "dd $tfile-1 failed"; return 2; }
2137         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2138                 { error "setstripe -c -1 failed"; return 3; }
2139         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2140                 { error "dd $tfile-2 failed"; return 4; }
2141
2142         # make sure write RPCs have been sent to OSTs
2143         sync; sleep 5; sync
2144
2145         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2146         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2147 }
2148 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2149
2150 test_27A() { # b=19102
2151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2152
2153         save_layout_restore_at_exit $MOUNT
2154         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2155         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2156                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2157         local default_size=$($LFS getstripe -S $MOUNT)
2158         local default_offset=$($LFS getstripe -i $MOUNT)
2159         local dsize=$(do_facet $SINGLEMDS \
2160                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2161         [ $default_size -eq $dsize ] ||
2162                 error "stripe size $default_size != $dsize"
2163         [ $default_offset -eq -1 ] ||
2164                 error "stripe offset $default_offset != -1"
2165 }
2166 run_test 27A "check filesystem-wide default LOV EA values"
2167
2168 test_27B() { # LU-2523
2169         test_mkdir $DIR/$tdir
2170         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2171         touch $DIR/$tdir/f0
2172         # open f1 with O_LOV_DELAY_CREATE
2173         # rename f0 onto f1
2174         # call setstripe ioctl on open file descriptor for f1
2175         # close
2176         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2177                 $DIR/$tdir/f0
2178
2179         rm -f $DIR/$tdir/f1
2180         # open f1 with O_LOV_DELAY_CREATE
2181         # unlink f1
2182         # call setstripe ioctl on open file descriptor for f1
2183         # close
2184         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2185
2186         # Allow multiop to fail in imitation of NFS's busted semantics.
2187         true
2188 }
2189 run_test 27B "call setstripe on open unlinked file/rename victim"
2190
2191 test_27C() { #LU-2871
2192         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2193
2194         declare -a ost_idx
2195         local index
2196         local found
2197         local i
2198         local j
2199
2200         test_mkdir $DIR/$tdir
2201         cd $DIR/$tdir
2202         for i in $(seq 0 $((OSTCOUNT - 1))); do
2203                 # set stripe across all OSTs starting from OST$i
2204                 $LFS setstripe -i $i -c -1 $tfile$i
2205                 # get striping information
2206                 ost_idx=($($LFS getstripe $tfile$i |
2207                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2208                 echo ${ost_idx[@]}
2209
2210                 # check the layout
2211                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2212                         error "${#ost_idx[@]} != $OSTCOUNT"
2213
2214                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2215                         found=0
2216                         for j in $(echo ${ost_idx[@]}); do
2217                                 if [ $index -eq $j ]; then
2218                                         found=1
2219                                         break
2220                                 fi
2221                         done
2222                         [ $found = 1 ] ||
2223                                 error "Can not find $index in ${ost_idx[@]}"
2224                 done
2225         done
2226 }
2227 run_test 27C "check full striping across all OSTs"
2228
2229 test_27D() {
2230         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2231         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2232         remote_mds_nodsh && skip "remote MDS with nodsh"
2233
2234         local POOL=${POOL:-testpool}
2235         local first_ost=0
2236         local last_ost=$(($OSTCOUNT - 1))
2237         local ost_step=1
2238         local ost_list=$(seq $first_ost $ost_step $last_ost)
2239         local ost_range="$first_ost $last_ost $ost_step"
2240
2241         if ! combined_mgs_mds ; then
2242                 mount_mgs_client
2243         fi
2244
2245         test_mkdir $DIR/$tdir
2246         pool_add $POOL || error "pool_add failed"
2247         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2248
2249         local skip27D
2250         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2251                 skip27D+="-s 29"
2252         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2253                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2254                         skip27D+=" -s 30,31"
2255         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2256                 error "llapi_layout_test failed"
2257
2258         destroy_test_pools || error "destroy test pools failed"
2259
2260         if ! combined_mgs_mds ; then
2261                 umount_mgs_client
2262         fi
2263 }
2264 run_test 27D "validate llapi_layout API"
2265
2266 # Verify that default_easize is increased from its initial value after
2267 # accessing a widely striped file.
2268 test_27E() {
2269         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2270         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2271                 skip "client does not have LU-3338 fix"
2272
2273         # 72 bytes is the minimum space required to store striping
2274         # information for a file striped across one OST:
2275         # (sizeof(struct lov_user_md_v3) +
2276         #  sizeof(struct lov_user_ost_data_v1))
2277         local min_easize=72
2278         $LCTL set_param -n llite.*.default_easize $min_easize ||
2279                 error "lctl set_param failed"
2280         local easize=$($LCTL get_param -n llite.*.default_easize)
2281
2282         [ $easize -eq $min_easize ] ||
2283                 error "failed to set default_easize"
2284
2285         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2286                 error "setstripe failed"
2287         cat $DIR/$tfile
2288         rm $DIR/$tfile
2289
2290         easize=$($LCTL get_param -n llite.*.default_easize)
2291
2292         [ $easize -gt $min_easize ] ||
2293                 error "default_easize not updated"
2294 }
2295 run_test 27E "check that default extended attribute size properly increases"
2296
2297 test_27F() { # LU-5346/LU-7975
2298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2299         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2300         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2301                 skip "Need MDS version at least 2.8.51"
2302         remote_ost_nodsh && skip "remote OST with nodsh"
2303
2304         test_mkdir $DIR/$tdir
2305         rm -f $DIR/$tdir/f0
2306         $LFS setstripe -c 2 $DIR/$tdir
2307
2308         # stop all OSTs to reproduce situation for LU-7975 ticket
2309         for num in $(seq $OSTCOUNT); do
2310                 stop ost$num
2311         done
2312
2313         # open/create f0 with O_LOV_DELAY_CREATE
2314         # truncate f0 to a non-0 size
2315         # close
2316         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2317
2318         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2319         # open/write it again to force delayed layout creation
2320         cat /etc/hosts > $DIR/$tdir/f0 &
2321         catpid=$!
2322
2323         # restart OSTs
2324         for num in $(seq $OSTCOUNT); do
2325                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2326                         error "ost$num failed to start"
2327         done
2328
2329         wait $catpid || error "cat failed"
2330
2331         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2332         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2333                 error "wrong stripecount"
2334
2335 }
2336 run_test 27F "Client resend delayed layout creation with non-zero size"
2337
2338 test_27G() { #LU-10629
2339         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2340                 skip "Need MDS version at least 2.11.51"
2341         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2342         remote_mds_nodsh && skip "remote MDS with nodsh"
2343         local POOL=${POOL:-testpool}
2344         local ostrange="0 0 1"
2345
2346         test_mkdir $DIR/$tdir
2347         pool_add $POOL || error "pool_add failed"
2348         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2349         $LFS setstripe -p $POOL $DIR/$tdir
2350
2351         local pool=$($LFS getstripe -p $DIR/$tdir)
2352
2353         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2354
2355         $LFS setstripe -d $DIR/$tdir
2356
2357         pool=$($LFS getstripe -p $DIR/$tdir)
2358
2359         rmdir $DIR/$tdir
2360
2361         [ -z "$pool" ] || error "'$pool' is not empty"
2362 }
2363 run_test 27G "Clear OST pool from stripe"
2364
2365 test_27H() {
2366         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2367                 skip "Need MDS version newer than 2.11.54"
2368         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2369         test_mkdir $DIR/$tdir
2370         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2371         touch $DIR/$tdir/$tfile
2372         $LFS getstripe -c $DIR/$tdir/$tfile
2373         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2374                 error "two-stripe file doesn't have two stripes"
2375
2376         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2377         $LFS getstripe -y $DIR/$tdir/$tfile
2378         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2379              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2380                 error "expected l_ost_idx: [02]$ not matched"
2381
2382         # make sure ost list has been cleared
2383         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2384         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2385                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2386         touch $DIR/$tdir/f3
2387         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2388 }
2389 run_test 27H "Set specific OSTs stripe"
2390
2391 test_27I() {
2392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2393         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2394         local pool=$TESTNAME
2395         local ostrange="1 1 1"
2396
2397         save_layout_restore_at_exit $MOUNT
2398         $LFS setstripe -c 2 -i 0 $MOUNT
2399         pool_add $pool || error "pool_add failed"
2400         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2401         test_mkdir $DIR/$tdir
2402         $LFS setstripe -p $pool $DIR/$tdir
2403         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2404         $LFS getstripe $DIR/$tdir/$tfile
2405 }
2406 run_test 27I "check that root dir striping does not break parent dir one"
2407
2408 # createtest also checks that device nodes are created and
2409 # then visible correctly (#2091)
2410 test_28() { # bug 2091
2411         test_mkdir $DIR/d28
2412         $CREATETEST $DIR/d28/ct || error "createtest failed"
2413 }
2414 run_test 28 "create/mknod/mkdir with bad file types ============"
2415
2416 test_29() {
2417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2418
2419         sync; sleep 1; sync # flush out any dirty pages from previous tests
2420         cancel_lru_locks
2421         test_mkdir $DIR/d29
2422         touch $DIR/d29/foo
2423         log 'first d29'
2424         ls -l $DIR/d29
2425
2426         declare -i LOCKCOUNTORIG=0
2427         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2428                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
2429         done
2430         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
2431
2432         declare -i LOCKUNUSEDCOUNTORIG=0
2433         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2434                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
2435         done
2436
2437         log 'second d29'
2438         ls -l $DIR/d29
2439         log 'done'
2440
2441         declare -i LOCKCOUNTCURRENT=0
2442         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2443                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
2444         done
2445
2446         declare -i LOCKUNUSEDCOUNTCURRENT=0
2447         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2448                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
2449         done
2450
2451         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
2452                 $LCTL set_param -n ldlm.dump_namespaces ""
2453                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
2454                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2455                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2456                 return 2
2457         fi
2458         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
2459                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
2460                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2461                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2462                 return 3
2463         fi
2464 }
2465 run_test 29 "IT_GETATTR regression  ============================"
2466
2467 test_30a() { # was test_30
2468         cp $(which ls) $DIR || cp /bin/ls $DIR
2469         $DIR/ls / || error "Can't execute binary from lustre"
2470         rm $DIR/ls
2471 }
2472 run_test 30a "execute binary from Lustre (execve) =============="
2473
2474 test_30b() {
2475         cp `which ls` $DIR || cp /bin/ls $DIR
2476         chmod go+rx $DIR/ls
2477         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
2478         rm $DIR/ls
2479 }
2480 run_test 30b "execute binary from Lustre as non-root ==========="
2481
2482 test_30c() { # b=22376
2483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2484
2485         cp `which ls` $DIR || cp /bin/ls $DIR
2486         chmod a-rw $DIR/ls
2487         cancel_lru_locks mdc
2488         cancel_lru_locks osc
2489         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
2490         rm -f $DIR/ls
2491 }
2492 run_test 30c "execute binary from Lustre without read perms ===="
2493
2494 test_31a() {
2495         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
2496         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
2497 }
2498 run_test 31a "open-unlink file =================================="
2499
2500 test_31b() {
2501         touch $DIR/f31 || error "touch $DIR/f31 failed"
2502         ln $DIR/f31 $DIR/f31b || error "ln failed"
2503         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
2504         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
2505 }
2506 run_test 31b "unlink file with multiple links while open ======="
2507
2508 test_31c() {
2509         touch $DIR/f31 || error "touch $DIR/f31 failed"
2510         ln $DIR/f31 $DIR/f31c || error "ln failed"
2511         multiop_bg_pause $DIR/f31 O_uc ||
2512                 error "multiop_bg_pause for $DIR/f31 failed"
2513         MULTIPID=$!
2514         $MULTIOP $DIR/f31c Ouc
2515         kill -USR1 $MULTIPID
2516         wait $MULTIPID
2517 }
2518 run_test 31c "open-unlink file with multiple links ============="
2519
2520 test_31d() {
2521         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
2522         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
2523 }
2524 run_test 31d "remove of open directory ========================="
2525
2526 test_31e() { # bug 2904
2527         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
2528 }
2529 run_test 31e "remove of open non-empty directory ==============="
2530
2531 test_31f() { # bug 4554
2532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2533
2534         set -vx
2535         test_mkdir $DIR/d31f
2536         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2537         cp /etc/hosts $DIR/d31f
2538         ls -l $DIR/d31f
2539         $LFS getstripe $DIR/d31f/hosts
2540         multiop_bg_pause $DIR/d31f D_c || return 1
2541         MULTIPID=$!
2542
2543         rm -rv $DIR/d31f || error "first of $DIR/d31f"
2544         test_mkdir $DIR/d31f
2545         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2546         cp /etc/hosts $DIR/d31f
2547         ls -l $DIR/d31f
2548         $LFS getstripe $DIR/d31f/hosts
2549         multiop_bg_pause $DIR/d31f D_c || return 1
2550         MULTIPID2=$!
2551
2552         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
2553         wait $MULTIPID || error "first opendir $MULTIPID failed"
2554
2555         sleep 6
2556
2557         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
2558         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
2559         set +vx
2560 }
2561 run_test 31f "remove of open directory with open-unlink file ==="
2562
2563 test_31g() {
2564         echo "-- cross directory link --"
2565         test_mkdir -c1 $DIR/${tdir}ga
2566         test_mkdir -c1 $DIR/${tdir}gb
2567         touch $DIR/${tdir}ga/f
2568         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
2569         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
2570         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
2571         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
2572         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
2573 }
2574 run_test 31g "cross directory link==============="
2575
2576 test_31h() {
2577         echo "-- cross directory link --"
2578         test_mkdir -c1 $DIR/${tdir}
2579         test_mkdir -c1 $DIR/${tdir}/dir
2580         touch $DIR/${tdir}/f
2581         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
2582         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
2583         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
2584         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
2585         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
2586 }
2587 run_test 31h "cross directory link under child==============="
2588
2589 test_31i() {
2590         echo "-- cross directory link --"
2591         test_mkdir -c1 $DIR/$tdir
2592         test_mkdir -c1 $DIR/$tdir/dir
2593         touch $DIR/$tdir/dir/f
2594         ln $DIR/$tdir/dir/f $DIR/$tdir/g
2595         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
2596         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
2597         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
2598         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
2599 }
2600 run_test 31i "cross directory link under parent==============="
2601
2602 test_31j() {
2603         test_mkdir -c1 -p $DIR/$tdir
2604         test_mkdir -c1 -p $DIR/$tdir/dir1
2605         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
2606         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
2607         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
2608         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
2609         return 0
2610 }
2611 run_test 31j "link for directory==============="
2612
2613 test_31k() {
2614         test_mkdir -c1 -p $DIR/$tdir
2615         touch $DIR/$tdir/s
2616         touch $DIR/$tdir/exist
2617         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
2618         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
2619         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
2620         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
2621         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
2622         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
2623         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
2624         return 0
2625 }
2626 run_test 31k "link to file: the same, non-existing, dir==============="
2627
2628 test_31m() {
2629         mkdir $DIR/d31m
2630         touch $DIR/d31m/s
2631         mkdir $DIR/d31m2
2632         touch $DIR/d31m2/exist
2633         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
2634         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
2635         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
2636         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
2637         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
2638         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
2639         return 0
2640 }
2641 run_test 31m "link to file: the same, non-existing, dir==============="
2642
2643 test_31n() {
2644         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
2645         nlink=$(stat --format=%h $DIR/$tfile)
2646         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
2647         local fd=$(free_fd)
2648         local cmd="exec $fd<$DIR/$tfile"
2649         eval $cmd
2650         cmd="exec $fd<&-"
2651         trap "eval $cmd" EXIT
2652         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
2653         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
2654         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
2655         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
2656         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
2657         eval $cmd
2658 }
2659 run_test 31n "check link count of unlinked file"
2660
2661 link_one() {
2662         local TEMPNAME=$(mktemp $1_XXXXXX)
2663         mlink $TEMPNAME $1 2> /dev/null &&
2664                 echo "$BASHPID: link $TEMPNAME to $1 succeeded"
2665         munlink $TEMPNAME
2666 }
2667
2668 test_31o() { # LU-2901
2669         test_mkdir $DIR/$tdir
2670         for LOOP in $(seq 100); do
2671                 rm -f $DIR/$tdir/$tfile*
2672                 for THREAD in $(seq 8); do
2673                         link_one $DIR/$tdir/$tfile.$LOOP &
2674                 done
2675                 wait
2676                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
2677                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
2678                         error "$LINKS duplicate links to $tfile.$LOOP" &&
2679                         break || true
2680         done
2681 }
2682 run_test 31o "duplicate hard links with same filename"
2683
2684 test_31p() {
2685         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
2686
2687         test_mkdir $DIR/$tdir
2688         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
2689         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
2690
2691         opendirunlink $DIR/$tdir/striped_dir/test1 ||
2692                 error "open unlink test1 failed"
2693         opendirunlink $DIR/$tdir/striped_dir/test2 ||
2694                 error "open unlink test2 failed"
2695
2696         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
2697                 error "test1 still exists"
2698         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
2699                 error "test2 still exists"
2700 }
2701 run_test 31p "remove of open striped directory"
2702
2703 cleanup_test32_mount() {
2704         local rc=0
2705         trap 0
2706         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
2707         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
2708         losetup -d $loopdev || true
2709         rm -rf $DIR/$tdir
2710         return $rc
2711 }
2712
2713 test_32a() {
2714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2715
2716         echo "== more mountpoints and symlinks ================="
2717         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2718         trap cleanup_test32_mount EXIT
2719         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2720         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2721                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2722         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
2723                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
2724         cleanup_test32_mount
2725 }
2726 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
2727
2728 test_32b() {
2729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2730
2731         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2732         trap cleanup_test32_mount EXIT
2733         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2734         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2735                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2736         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
2737                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
2738         cleanup_test32_mount
2739 }
2740 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
2741
2742 test_32c() {
2743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2744
2745         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2746         trap cleanup_test32_mount EXIT
2747         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2748         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2749                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2750         test_mkdir -p $DIR/$tdir/d2/test_dir
2751         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
2752                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
2753         cleanup_test32_mount
2754 }
2755 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
2756
2757 test_32d() {
2758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2759
2760         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2761         trap cleanup_test32_mount EXIT
2762         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2763         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2764                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2765         test_mkdir -p $DIR/$tdir/d2/test_dir
2766         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
2767                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
2768         cleanup_test32_mount
2769 }
2770 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
2771
2772 test_32e() {
2773         rm -fr $DIR/$tdir
2774         test_mkdir -p $DIR/$tdir/tmp
2775         local tmp_dir=$DIR/$tdir/tmp
2776         ln -s $DIR/$tdir $tmp_dir/symlink11
2777         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
2778         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
2779         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
2780 }
2781 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
2782
2783 test_32f() {
2784         rm -fr $DIR/$tdir
2785         test_mkdir -p $DIR/$tdir/tmp
2786         local tmp_dir=$DIR/$tdir/tmp
2787         ln -s $DIR/$tdir $tmp_dir/symlink11
2788         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
2789         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
2790         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
2791 }
2792 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
2793
2794 test_32g() {
2795         local tmp_dir=$DIR/$tdir/tmp
2796         test_mkdir -p $tmp_dir
2797         test_mkdir $DIR/${tdir}2
2798         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
2799         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
2800         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
2801         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
2802         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
2803         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
2804 }
2805 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
2806
2807 test_32h() {
2808         rm -fr $DIR/$tdir $DIR/${tdir}2
2809         tmp_dir=$DIR/$tdir/tmp
2810         test_mkdir -p $tmp_dir
2811         test_mkdir $DIR/${tdir}2
2812         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
2813         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
2814         ls $tmp_dir/symlink12 || error "listing symlink12"
2815         ls $DIR/$tdir/symlink02  || error "listing symlink02"
2816 }
2817 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
2818
2819 test_32i() {
2820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2821
2822         [ -e $DIR/$tdir ] && 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         touch $DIR/$tdir/test_file
2828         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
2829                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
2830         cleanup_test32_mount
2831 }
2832 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
2833
2834 test_32j() {
2835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2836
2837         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2838         trap cleanup_test32_mount EXIT
2839         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2840         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2841                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2842         touch $DIR/$tdir/test_file
2843         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
2844                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
2845         cleanup_test32_mount
2846 }
2847 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
2848
2849 test_32k() {
2850         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2851
2852         rm -fr $DIR/$tdir
2853         trap cleanup_test32_mount EXIT
2854         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2855         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2856                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2857         test_mkdir -p $DIR/$tdir/d2
2858         touch $DIR/$tdir/d2/test_file || error "touch failed"
2859         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
2860                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
2861         cleanup_test32_mount
2862 }
2863 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
2864
2865 test_32l() {
2866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2867
2868         rm -fr $DIR/$tdir
2869         trap cleanup_test32_mount EXIT
2870         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2871         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2872                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2873         test_mkdir -p $DIR/$tdir/d2
2874         touch $DIR/$tdir/d2/test_file || error "touch failed"
2875         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
2876                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
2877         cleanup_test32_mount
2878 }
2879 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
2880
2881 test_32m() {
2882         rm -fr $DIR/d32m
2883         test_mkdir -p $DIR/d32m/tmp
2884         TMP_DIR=$DIR/d32m/tmp
2885         ln -s $DIR $TMP_DIR/symlink11
2886         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
2887         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
2888                 error "symlink11 not a link"
2889         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
2890                 error "symlink01 not a link"
2891 }
2892 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
2893
2894 test_32n() {
2895         rm -fr $DIR/d32n
2896         test_mkdir -p $DIR/d32n/tmp
2897         TMP_DIR=$DIR/d32n/tmp
2898         ln -s $DIR $TMP_DIR/symlink11
2899         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
2900         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
2901         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
2902 }
2903 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
2904
2905 test_32o() {
2906         touch $DIR/$tfile
2907         test_mkdir -p $DIR/d32o/tmp
2908         TMP_DIR=$DIR/d32o/tmp
2909         ln -s $DIR/$tfile $TMP_DIR/symlink12
2910         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
2911         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
2912                 error "symlink12 not a link"
2913         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
2914         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
2915                 error "$DIR/d32o/tmp/symlink12 not file type"
2916         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
2917                 error "$DIR/d32o/symlink02 not file type"
2918 }
2919 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
2920
2921 test_32p() {
2922         log 32p_1
2923         rm -fr $DIR/d32p
2924         log 32p_2
2925         rm -f $DIR/$tfile
2926         log 32p_3
2927         touch $DIR/$tfile
2928         log 32p_4
2929         test_mkdir -p $DIR/d32p/tmp
2930         log 32p_5
2931         TMP_DIR=$DIR/d32p/tmp
2932         log 32p_6
2933         ln -s $DIR/$tfile $TMP_DIR/symlink12
2934         log 32p_7
2935         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
2936         log 32p_8
2937         cat $DIR/d32p/tmp/symlink12 ||
2938                 error "Can't open $DIR/d32p/tmp/symlink12"
2939         log 32p_9
2940         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
2941         log 32p_10
2942 }
2943 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
2944
2945 test_32q() {
2946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2947
2948         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2949         trap cleanup_test32_mount EXIT
2950         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2951         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
2952         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2953                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2954         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
2955         cleanup_test32_mount
2956 }
2957 run_test 32q "stat follows mountpoints in Lustre (should return error)"
2958
2959 test_32r() {
2960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2961
2962         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2963         trap cleanup_test32_mount EXIT
2964         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2965         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
2966         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2967                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2968         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
2969         cleanup_test32_mount
2970 }
2971 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
2972
2973 test_33aa() {
2974         rm -f $DIR/$tfile
2975         touch $DIR/$tfile
2976         chmod 444 $DIR/$tfile
2977         chown $RUNAS_ID $DIR/$tfile
2978         log 33_1
2979         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
2980         log 33_2
2981 }
2982 run_test 33aa "write file with mode 444 (should return error)"
2983
2984 test_33a() {
2985         rm -fr $DIR/$tdir
2986         test_mkdir $DIR/$tdir
2987         chown $RUNAS_ID $DIR/$tdir
2988         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
2989                 error "$RUNAS create $tdir/$tfile failed"
2990         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
2991                 error "open RDWR" || true
2992 }
2993 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
2994
2995 test_33b() {
2996         rm -fr $DIR/$tdir
2997         test_mkdir $DIR/$tdir
2998         chown $RUNAS_ID $DIR/$tdir
2999         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3000 }
3001 run_test 33b "test open file with malformed flags (No panic)"
3002
3003 test_33c() {
3004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3005         remote_ost_nodsh && skip "remote OST with nodsh"
3006
3007         local ostnum
3008         local ostname
3009         local write_bytes
3010         local all_zeros
3011
3012         all_zeros=:
3013         rm -fr $DIR/$tdir
3014         test_mkdir $DIR/$tdir
3015         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3016
3017         sync
3018         for ostnum in $(seq $OSTCOUNT); do
3019                 # test-framework's OST numbering is one-based, while Lustre's
3020                 # is zero-based
3021                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3022                 # Parsing llobdstat's output sucks; we could grep the /proc
3023                 # path, but that's likely to not be as portable as using the
3024                 # llobdstat utility.  So we parse lctl output instead.
3025                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3026                         obdfilter/$ostname/stats |
3027                         awk '/^write_bytes/ {print $7}' )
3028                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3029                 if (( ${write_bytes:-0} > 0 ))
3030                 then
3031                         all_zeros=false
3032                         break;
3033                 fi
3034         done
3035
3036         $all_zeros || return 0
3037
3038         # Write four bytes
3039         echo foo > $DIR/$tdir/bar
3040         # Really write them
3041         sync
3042
3043         # Total up write_bytes after writing.  We'd better find non-zeros.
3044         for ostnum in $(seq $OSTCOUNT); do
3045                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3046                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3047                         obdfilter/$ostname/stats |
3048                         awk '/^write_bytes/ {print $7}' )
3049                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3050                 if (( ${write_bytes:-0} > 0 ))
3051                 then
3052                         all_zeros=false
3053                         break;
3054                 fi
3055         done
3056
3057         if $all_zeros
3058         then
3059                 for ostnum in $(seq $OSTCOUNT); do
3060                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3061                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3062                         do_facet ost$ostnum lctl get_param -n \
3063                                 obdfilter/$ostname/stats
3064                 done
3065                 error "OST not keeping write_bytes stats (b22312)"
3066         fi
3067 }
3068 run_test 33c "test llobdstat and write_bytes"
3069
3070 test_33d() {
3071         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3073
3074         local MDTIDX=1
3075         local remote_dir=$DIR/$tdir/remote_dir
3076
3077         test_mkdir $DIR/$tdir
3078         $LFS mkdir -i $MDTIDX $remote_dir ||
3079                 error "create remote directory failed"
3080
3081         touch $remote_dir/$tfile
3082         chmod 444 $remote_dir/$tfile
3083         chown $RUNAS_ID $remote_dir/$tfile
3084
3085         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3086
3087         chown $RUNAS_ID $remote_dir
3088         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3089                                         error "create" || true
3090         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3091                                     error "open RDWR" || true
3092         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3093 }
3094 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3095
3096 test_33e() {
3097         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3098
3099         mkdir $DIR/$tdir
3100
3101         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3102         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3103         mkdir $DIR/$tdir/local_dir
3104
3105         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3106         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3107         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3108
3109         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3110                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3111
3112         rmdir $DIR/$tdir/* || error "rmdir failed"
3113
3114         umask 777
3115         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3116         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3117         mkdir $DIR/$tdir/local_dir
3118
3119         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3120         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3121         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3122
3123         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3124                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3125
3126         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3127
3128         umask 000
3129         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3130         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3131         mkdir $DIR/$tdir/local_dir
3132
3133         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3134         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3135         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3136
3137         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3138                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3139 }
3140 run_test 33e "mkdir and striped directory should have same mode"
3141
3142 cleanup_33f() {
3143         trap 0
3144         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3145 }
3146
3147 test_33f() {
3148         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3149         remote_mds_nodsh && skip "remote MDS with nodsh"
3150
3151         mkdir $DIR/$tdir
3152         chmod go+rwx $DIR/$tdir
3153         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3154         trap cleanup_33f EXIT
3155
3156         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3157                 error "cannot create striped directory"
3158
3159         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3160                 error "cannot create files in striped directory"
3161
3162         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3163                 error "cannot remove files in striped directory"
3164
3165         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3166                 error "cannot remove striped directory"
3167
3168         cleanup_33f
3169 }
3170 run_test 33f "nonroot user can create, access, and remove a striped directory"
3171
3172 test_33g() {
3173         mkdir -p $DIR/$tdir/dir2
3174
3175         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3176         echo $err
3177         [[ $err =~ "exists" ]] || error "Not exists error"
3178 }
3179 run_test 33g "nonroot user create already existing root created file"
3180
3181 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3182 test_34a() {
3183         rm -f $DIR/f34
3184         $MCREATE $DIR/f34 || error "mcreate failed"
3185         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3186                 error "getstripe failed"
3187         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3188         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3189                 error "getstripe failed"
3190         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3191                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3192 }
3193 run_test 34a "truncate file that has not been opened ==========="
3194
3195 test_34b() {
3196         [ ! -f $DIR/f34 ] && test_34a
3197         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3198                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3199         $OPENFILE -f O_RDONLY $DIR/f34
3200         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3201                 error "getstripe failed"
3202         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3203                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3204 }
3205 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3206
3207 test_34c() {
3208         [ ! -f $DIR/f34 ] && test_34a
3209         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3210                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3211         $OPENFILE -f O_RDWR $DIR/f34
3212         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3213                 error "$LFS getstripe failed"
3214         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3215                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3216 }
3217 run_test 34c "O_RDWR opening file-with-size works =============="
3218
3219 test_34d() {
3220         [ ! -f $DIR/f34 ] && test_34a
3221         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3222                 error "dd failed"
3223         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3224                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3225         rm $DIR/f34
3226 }
3227 run_test 34d "write to sparse file ============================="
3228
3229 test_34e() {
3230         rm -f $DIR/f34e
3231         $MCREATE $DIR/f34e || error "mcreate failed"
3232         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3233         $CHECKSTAT -s 1000 $DIR/f34e ||
3234                 error "Size of $DIR/f34e not equal to 1000 bytes"
3235         $OPENFILE -f O_RDWR $DIR/f34e
3236         $CHECKSTAT -s 1000 $DIR/f34e ||
3237                 error "Size of $DIR/f34e not equal to 1000 bytes"
3238 }
3239 run_test 34e "create objects, some with size and some without =="
3240
3241 test_34f() { # bug 6242, 6243
3242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3243
3244         SIZE34F=48000
3245         rm -f $DIR/f34f
3246         $MCREATE $DIR/f34f || error "mcreate failed"
3247         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3248         dd if=$DIR/f34f of=$TMP/f34f
3249         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3250         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3251         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3252         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3253         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3254 }
3255 run_test 34f "read from a file with no objects until EOF ======="
3256
3257 test_34g() {
3258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3259
3260         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3261                 error "dd failed"
3262         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3263         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3264                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3265         cancel_lru_locks osc
3266         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3267                 error "wrong size after lock cancel"
3268
3269         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3270         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3271                 error "expanding truncate failed"
3272         cancel_lru_locks osc
3273         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3274                 error "wrong expanded size after lock cancel"
3275 }
3276 run_test 34g "truncate long file ==============================="
3277
3278 test_34h() {
3279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3280
3281         local gid=10
3282         local sz=1000
3283
3284         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3285         sync # Flush the cache so that multiop below does not block on cache
3286              # flush when getting the group lock
3287         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3288         MULTIPID=$!
3289
3290         # Since just timed wait is not good enough, let's do a sync write
3291         # that way we are sure enough time for a roundtrip + processing
3292         # passed + 2 seconds of extra margin.
3293         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3294         rm $DIR/${tfile}-1
3295         sleep 2
3296
3297         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3298                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3299                 kill -9 $MULTIPID
3300         fi
3301         wait $MULTIPID
3302         local nsz=`stat -c %s $DIR/$tfile`
3303         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3304 }
3305 run_test 34h "ftruncate file under grouplock should not block"
3306
3307 test_35a() {
3308         cp /bin/sh $DIR/f35a
3309         chmod 444 $DIR/f35a
3310         chown $RUNAS_ID $DIR/f35a
3311         $RUNAS $DIR/f35a && error || true
3312         rm $DIR/f35a
3313 }
3314 run_test 35a "exec file with mode 444 (should return and not leak)"
3315
3316 test_36a() {
3317         rm -f $DIR/f36
3318         utime $DIR/f36 || error "utime failed for MDS"
3319 }
3320 run_test 36a "MDS utime check (mknod, utime)"
3321
3322 test_36b() {
3323         echo "" > $DIR/f36
3324         utime $DIR/f36 || error "utime failed for OST"
3325 }
3326 run_test 36b "OST utime check (open, utime)"
3327
3328 test_36c() {
3329         rm -f $DIR/d36/f36
3330         test_mkdir $DIR/d36
3331         chown $RUNAS_ID $DIR/d36
3332         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3333 }
3334 run_test 36c "non-root MDS utime check (mknod, utime)"
3335
3336 test_36d() {
3337         [ ! -d $DIR/d36 ] && test_36c
3338         echo "" > $DIR/d36/f36
3339         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3340 }
3341 run_test 36d "non-root OST utime check (open, utime)"
3342
3343 test_36e() {
3344         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3345
3346         test_mkdir $DIR/$tdir
3347         touch $DIR/$tdir/$tfile
3348         $RUNAS utime $DIR/$tdir/$tfile &&
3349                 error "utime worked, expected failure" || true
3350 }
3351 run_test 36e "utime on non-owned file (should return error)"
3352
3353 subr_36fh() {
3354         local fl="$1"
3355         local LANG_SAVE=$LANG
3356         local LC_LANG_SAVE=$LC_LANG
3357         export LANG=C LC_LANG=C # for date language
3358
3359         DATESTR="Dec 20  2000"
3360         test_mkdir $DIR/$tdir
3361         lctl set_param fail_loc=$fl
3362         date; date +%s
3363         cp /etc/hosts $DIR/$tdir/$tfile
3364         sync & # write RPC generated with "current" inode timestamp, but delayed
3365         sleep 1
3366         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3367         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3368         cancel_lru_locks $OSC
3369         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3370         date; date +%s
3371         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3372                 echo "BEFORE: $LS_BEFORE" && \
3373                 echo "AFTER : $LS_AFTER" && \
3374                 echo "WANT  : $DATESTR" && \
3375                 error "$DIR/$tdir/$tfile timestamps changed" || true
3376
3377         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3378 }
3379
3380 test_36f() {
3381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3382
3383         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3384         subr_36fh "0x80000214"
3385 }
3386 run_test 36f "utime on file racing with OST BRW write =========="
3387
3388 test_36g() {
3389         remote_ost_nodsh && skip "remote OST with nodsh"
3390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3391         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
3392                 skip "Need MDS version at least 2.12.51"
3393
3394         local fmd_max_age
3395         local fmd
3396         local facet="ost1"
3397         local tgt="obdfilter"
3398
3399         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
3400
3401         test_mkdir $DIR/$tdir
3402         fmd_max_age=$(do_facet $facet \
3403                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
3404                 head -n 1")
3405
3406         echo "FMD max age: ${fmd_max_age}s"
3407         touch $DIR/$tdir/$tfile
3408         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3409                 gawk '{cnt=cnt+$1}  END{print cnt}')
3410         echo "FMD before: $fmd"
3411         [[ $fmd == 0 ]] &&
3412                 error "FMD wasn't create by touch"
3413         sleep $((fmd_max_age + 12))
3414         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3415                 gawk '{cnt=cnt+$1}  END{print cnt}')
3416         echo "FMD after: $fmd"
3417         [[ $fmd == 0 ]] ||
3418                 error "FMD wasn't expired by ping"
3419 }
3420 run_test 36g "FMD cache expiry ====================="
3421
3422 test_36h() {
3423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3424
3425         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
3426         subr_36fh "0x80000227"
3427 }
3428 run_test 36h "utime on file racing with OST BRW write =========="
3429
3430 test_36i() {
3431         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3432
3433         test_mkdir $DIR/$tdir
3434         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
3435
3436         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
3437         local new_mtime=$((mtime + 200))
3438
3439         #change Modify time of striped dir
3440         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
3441                         error "change mtime failed"
3442
3443         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
3444
3445         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
3446 }
3447 run_test 36i "change mtime on striped directory"
3448
3449 # test_37 - duplicate with tests 32q 32r
3450
3451 test_38() {
3452         local file=$DIR/$tfile
3453         touch $file
3454         openfile -f O_DIRECTORY $file
3455         local RC=$?
3456         local ENOTDIR=20
3457         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
3458         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
3459 }
3460 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
3461
3462 test_39a() { # was test_39
3463         touch $DIR/$tfile
3464         touch $DIR/${tfile}2
3465 #       ls -l  $DIR/$tfile $DIR/${tfile}2
3466 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
3467 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
3468         sleep 2
3469         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
3470         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
3471                 echo "mtime"
3472                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
3473                 echo "atime"
3474                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
3475                 echo "ctime"
3476                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
3477                 error "O_TRUNC didn't change timestamps"
3478         fi
3479 }
3480 run_test 39a "mtime changed on create"
3481
3482 test_39b() {
3483         test_mkdir -c1 $DIR/$tdir
3484         cp -p /etc/passwd $DIR/$tdir/fopen
3485         cp -p /etc/passwd $DIR/$tdir/flink
3486         cp -p /etc/passwd $DIR/$tdir/funlink
3487         cp -p /etc/passwd $DIR/$tdir/frename
3488         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
3489
3490         sleep 1
3491         echo "aaaaaa" >> $DIR/$tdir/fopen
3492         echo "aaaaaa" >> $DIR/$tdir/flink
3493         echo "aaaaaa" >> $DIR/$tdir/funlink
3494         echo "aaaaaa" >> $DIR/$tdir/frename
3495
3496         local open_new=`stat -c %Y $DIR/$tdir/fopen`
3497         local link_new=`stat -c %Y $DIR/$tdir/flink`
3498         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
3499         local rename_new=`stat -c %Y $DIR/$tdir/frename`
3500
3501         cat $DIR/$tdir/fopen > /dev/null
3502         ln $DIR/$tdir/flink $DIR/$tdir/flink2
3503         rm -f $DIR/$tdir/funlink2
3504         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
3505
3506         for (( i=0; i < 2; i++ )) ; do
3507                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
3508                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
3509                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
3510                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
3511
3512                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
3513                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
3514                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
3515                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
3516
3517                 cancel_lru_locks $OSC
3518                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3519         done
3520 }
3521 run_test 39b "mtime change on open, link, unlink, rename  ======"
3522
3523 # this should be set to past
3524 TEST_39_MTIME=`date -d "1 year ago" +%s`
3525
3526 # bug 11063
3527 test_39c() {
3528         touch $DIR1/$tfile
3529         sleep 2
3530         local mtime0=`stat -c %Y $DIR1/$tfile`
3531
3532         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3533         local mtime1=`stat -c %Y $DIR1/$tfile`
3534         [ "$mtime1" = $TEST_39_MTIME ] || \
3535                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
3536
3537         local d1=`date +%s`
3538         echo hello >> $DIR1/$tfile
3539         local d2=`date +%s`
3540         local mtime2=`stat -c %Y $DIR1/$tfile`
3541         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
3542                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
3543
3544         mv $DIR1/$tfile $DIR1/$tfile-1
3545
3546         for (( i=0; i < 2; i++ )) ; do
3547                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
3548                 [ "$mtime2" = "$mtime3" ] || \
3549                         error "mtime ($mtime2) changed (to $mtime3) on rename"
3550
3551                 cancel_lru_locks $OSC
3552                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3553         done
3554 }
3555 run_test 39c "mtime change on rename ==========================="
3556
3557 # bug 21114
3558 test_39d() {
3559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3560
3561         touch $DIR1/$tfile
3562         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3563
3564         for (( i=0; i < 2; i++ )) ; do
3565                 local mtime=`stat -c %Y $DIR1/$tfile`
3566                 [ $mtime = $TEST_39_MTIME ] || \
3567                         error "mtime($mtime) is not set to $TEST_39_MTIME"
3568
3569                 cancel_lru_locks $OSC
3570                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3571         done
3572 }
3573 run_test 39d "create, utime, stat =============================="
3574
3575 # bug 21114
3576 test_39e() {
3577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3578
3579         touch $DIR1/$tfile
3580         local mtime1=`stat -c %Y $DIR1/$tfile`
3581
3582         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3583
3584         for (( i=0; i < 2; i++ )) ; do
3585                 local mtime2=`stat -c %Y $DIR1/$tfile`
3586                 [ $mtime2 = $TEST_39_MTIME ] || \
3587                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
3588
3589                 cancel_lru_locks $OSC
3590                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3591         done
3592 }
3593 run_test 39e "create, stat, utime, stat ========================"
3594
3595 # bug 21114
3596 test_39f() {
3597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3598
3599         touch $DIR1/$tfile
3600         mtime1=`stat -c %Y $DIR1/$tfile`
3601
3602         sleep 2
3603         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3604
3605         for (( i=0; i < 2; i++ )) ; do
3606                 local mtime2=`stat -c %Y $DIR1/$tfile`
3607                 [ $mtime2 = $TEST_39_MTIME ] || \
3608                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
3609
3610                 cancel_lru_locks $OSC
3611                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3612         done
3613 }
3614 run_test 39f "create, stat, sleep, utime, stat ================="
3615
3616 # bug 11063
3617 test_39g() {
3618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3619
3620         echo hello >> $DIR1/$tfile
3621         local mtime1=`stat -c %Y $DIR1/$tfile`
3622
3623         sleep 2
3624         chmod o+r $DIR1/$tfile
3625
3626         for (( i=0; i < 2; i++ )) ; do
3627                 local mtime2=`stat -c %Y $DIR1/$tfile`
3628                 [ "$mtime1" = "$mtime2" ] || \
3629                         error "lost mtime: $mtime2, should be $mtime1"
3630
3631                 cancel_lru_locks $OSC
3632                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3633         done
3634 }
3635 run_test 39g "write, chmod, stat ==============================="
3636
3637 # bug 11063
3638 test_39h() {
3639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3640
3641         touch $DIR1/$tfile
3642         sleep 1
3643
3644         local d1=`date`
3645         echo hello >> $DIR1/$tfile
3646         local mtime1=`stat -c %Y $DIR1/$tfile`
3647
3648         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3649         local d2=`date`
3650         if [ "$d1" != "$d2" ]; then
3651                 echo "write and touch not within one second"
3652         else
3653                 for (( i=0; i < 2; i++ )) ; do
3654                         local mtime2=`stat -c %Y $DIR1/$tfile`
3655                         [ "$mtime2" = $TEST_39_MTIME ] || \
3656                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
3657
3658                         cancel_lru_locks $OSC
3659                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3660                 done
3661         fi
3662 }
3663 run_test 39h "write, utime within one second, stat ============="
3664
3665 test_39i() {
3666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3667
3668         touch $DIR1/$tfile
3669         sleep 1
3670
3671         echo hello >> $DIR1/$tfile
3672         local mtime1=`stat -c %Y $DIR1/$tfile`
3673
3674         mv $DIR1/$tfile $DIR1/$tfile-1
3675
3676         for (( i=0; i < 2; i++ )) ; do
3677                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
3678
3679                 [ "$mtime1" = "$mtime2" ] || \
3680                         error "lost mtime: $mtime2, should be $mtime1"
3681
3682                 cancel_lru_locks $OSC
3683                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3684         done
3685 }
3686 run_test 39i "write, rename, stat =============================="
3687
3688 test_39j() {
3689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3690
3691         start_full_debug_logging
3692         touch $DIR1/$tfile
3693         sleep 1
3694
3695         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
3696         lctl set_param fail_loc=0x80000412
3697         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
3698                 error "multiop failed"
3699         local multipid=$!
3700         local mtime1=`stat -c %Y $DIR1/$tfile`
3701
3702         mv $DIR1/$tfile $DIR1/$tfile-1
3703
3704         kill -USR1 $multipid
3705         wait $multipid || error "multiop close failed"
3706
3707         for (( i=0; i < 2; i++ )) ; do
3708                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
3709                 [ "$mtime1" = "$mtime2" ] ||
3710                         error "mtime is lost on close: $mtime2, " \
3711                               "should be $mtime1"
3712
3713                 cancel_lru_locks $OSC
3714                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3715         done
3716         lctl set_param fail_loc=0
3717         stop_full_debug_logging
3718 }
3719 run_test 39j "write, rename, close, stat ======================="
3720
3721 test_39k() {
3722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3723
3724         touch $DIR1/$tfile
3725         sleep 1
3726
3727         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
3728         local multipid=$!
3729         local mtime1=`stat -c %Y $DIR1/$tfile`
3730
3731         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3732
3733         kill -USR1 $multipid
3734         wait $multipid || error "multiop close failed"
3735
3736         for (( i=0; i < 2; i++ )) ; do
3737                 local mtime2=`stat -c %Y $DIR1/$tfile`
3738
3739                 [ "$mtime2" = $TEST_39_MTIME ] || \
3740                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
3741
3742                 cancel_lru_locks osc
3743                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3744         done
3745 }
3746 run_test 39k "write, utime, close, stat ========================"
3747
3748 # this should be set to future
3749 TEST_39_ATIME=`date -d "1 year" +%s`
3750
3751 test_39l() {
3752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3753         remote_mds_nodsh && skip "remote MDS with nodsh"
3754
3755         local atime_diff=$(do_facet $SINGLEMDS \
3756                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
3757         rm -rf $DIR/$tdir
3758         mkdir -p $DIR/$tdir
3759
3760         # test setting directory atime to future
3761         touch -a -d @$TEST_39_ATIME $DIR/$tdir
3762         local atime=$(stat -c %X $DIR/$tdir)
3763         [ "$atime" = $TEST_39_ATIME ] ||
3764                 error "atime is not set to future: $atime, $TEST_39_ATIME"
3765
3766         # test setting directory atime from future to now
3767         local now=$(date +%s)
3768         touch -a -d @$now $DIR/$tdir
3769
3770         atime=$(stat -c %X $DIR/$tdir)
3771         [ "$atime" -eq "$now"  ] ||
3772                 error "atime is not updated from future: $atime, $now"
3773
3774         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
3775         sleep 3
3776
3777         # test setting directory atime when now > dir atime + atime_diff
3778         local d1=$(date +%s)
3779         ls $DIR/$tdir
3780         local d2=$(date +%s)
3781         cancel_lru_locks mdc
3782         atime=$(stat -c %X $DIR/$tdir)
3783         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
3784                 error "atime is not updated  : $atime, should be $d2"
3785
3786         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
3787         sleep 3
3788
3789         # test not setting directory atime when now < dir atime + atime_diff
3790         ls $DIR/$tdir
3791         cancel_lru_locks mdc
3792         atime=$(stat -c %X $DIR/$tdir)
3793         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
3794                 error "atime is updated to $atime, should remain $d1<atime<$d2"
3795
3796         do_facet $SINGLEMDS \
3797                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
3798 }
3799 run_test 39l "directory atime update ==========================="
3800
3801 test_39m() {
3802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3803
3804         touch $DIR1/$tfile
3805         sleep 2
3806         local far_past_mtime=$(date -d "May 29 1953" +%s)
3807         local far_past_atime=$(date -d "Dec 17 1903" +%s)
3808
3809         touch -m -d @$far_past_mtime $DIR1/$tfile
3810         touch -a -d @$far_past_atime $DIR1/$tfile
3811
3812         for (( i=0; i < 2; i++ )) ; do
3813                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
3814                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
3815                         error "atime or mtime set incorrectly"
3816
3817                 cancel_lru_locks $OSC
3818                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3819         done
3820 }
3821 run_test 39m "test atime and mtime before 1970"
3822
3823 test_39n() { # LU-3832
3824         remote_mds_nodsh && skip "remote MDS with nodsh"
3825
3826         local atime_diff=$(do_facet $SINGLEMDS \
3827                 lctl get_param -n mdd.*MDT0000*.atime_diff)
3828         local atime0
3829         local atime1
3830         local atime2
3831
3832         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
3833
3834         rm -rf $DIR/$tfile
3835         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
3836         atime0=$(stat -c %X $DIR/$tfile)
3837
3838         sleep 5
3839         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
3840         atime1=$(stat -c %X $DIR/$tfile)
3841
3842         sleep 5
3843         cancel_lru_locks mdc
3844         cancel_lru_locks osc
3845         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
3846         atime2=$(stat -c %X $DIR/$tfile)
3847
3848         do_facet $SINGLEMDS \
3849                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
3850
3851         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
3852         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
3853 }
3854 run_test 39n "check that O_NOATIME is honored"
3855
3856 test_39o() {
3857         TESTDIR=$DIR/$tdir/$tfile
3858         [ -e $TESTDIR ] && rm -rf $TESTDIR
3859         mkdir -p $TESTDIR
3860         cd $TESTDIR
3861         links1=2
3862         ls
3863         mkdir a b
3864         ls
3865         links2=$(stat -c %h .)
3866         [ $(($links1 + 2)) != $links2 ] &&
3867                 error "wrong links count $(($links1 + 2)) != $links2"
3868         rmdir b
3869         links3=$(stat -c %h .)
3870         [ $(($links1 + 1)) != $links3 ] &&
3871                 error "wrong links count $links1 != $links3"
3872         return 0
3873 }
3874 run_test 39o "directory cached attributes updated after create"
3875
3876 test_39p() {
3877         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3878
3879         local MDTIDX=1
3880         TESTDIR=$DIR/$tdir/$tdir
3881         [ -e $TESTDIR ] && rm -rf $TESTDIR
3882         test_mkdir -p $TESTDIR
3883         cd $TESTDIR
3884         links1=2
3885         ls
3886         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
3887         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
3888         ls
3889         links2=$(stat -c %h .)
3890         [ $(($links1 + 2)) != $links2 ] &&
3891                 error "wrong links count $(($links1 + 2)) != $links2"
3892         rmdir remote_dir2
3893         links3=$(stat -c %h .)
3894         [ $(($links1 + 1)) != $links3 ] &&
3895                 error "wrong links count $links1 != $links3"
3896         return 0
3897 }
3898 run_test 39p "remote directory cached attributes updated after create ========"
3899
3900
3901 test_39q() { # LU-8041
3902         local testdir=$DIR/$tdir
3903         mkdir -p $testdir
3904         multiop_bg_pause $testdir D_c || error "multiop failed"
3905         local multipid=$!
3906         cancel_lru_locks mdc
3907         kill -USR1 $multipid
3908         local atime=$(stat -c %X $testdir)
3909         [ "$atime" -ne 0 ] || error "atime is zero"
3910 }
3911 run_test 39q "close won't zero out atime"
3912
3913 test_40() {
3914         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
3915         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
3916                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
3917         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
3918                 error "$tfile is not 4096 bytes in size"
3919 }
3920 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
3921
3922 test_41() {
3923         # bug 1553
3924         small_write $DIR/f41 18
3925 }
3926 run_test 41 "test small file write + fstat ====================="
3927
3928 count_ost_writes() {
3929         lctl get_param -n ${OSC}.*.stats |
3930                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
3931                         END { printf("%0.0f", writes) }'
3932 }
3933
3934 # decent default
3935 WRITEBACK_SAVE=500
3936 DIRTY_RATIO_SAVE=40
3937 MAX_DIRTY_RATIO=50
3938 BG_DIRTY_RATIO_SAVE=10
3939 MAX_BG_DIRTY_RATIO=25
3940
3941 start_writeback() {
3942         trap 0
3943         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
3944         # dirty_ratio, dirty_background_ratio
3945         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
3946                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
3947                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
3948                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
3949         else
3950                 # if file not here, we are a 2.4 kernel
3951                 kill -CONT `pidof kupdated`
3952         fi
3953 }
3954
3955 stop_writeback() {
3956         # setup the trap first, so someone cannot exit the test at the
3957         # exact wrong time and mess up a machine
3958         trap start_writeback EXIT
3959         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
3960         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
3961                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
3962                 sysctl -w vm.dirty_writeback_centisecs=0
3963                 sysctl -w vm.dirty_writeback_centisecs=0
3964                 # save and increase /proc/sys/vm/dirty_ratio
3965                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
3966                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
3967                 # save and increase /proc/sys/vm/dirty_background_ratio
3968                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
3969                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
3970         else
3971                 # if file not here, we are a 2.4 kernel
3972                 kill -STOP `pidof kupdated`
3973         fi
3974 }
3975
3976 # ensure that all stripes have some grant before we test client-side cache
3977 setup_test42() {
3978         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
3979                 dd if=/dev/zero of=$i bs=4k count=1
3980                 rm $i
3981         done
3982 }
3983
3984 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
3985 # file truncation, and file removal.
3986 test_42a() {
3987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3988
3989         setup_test42
3990         cancel_lru_locks $OSC
3991         stop_writeback
3992         sync; sleep 1; sync # just to be safe
3993         BEFOREWRITES=`count_ost_writes`
3994         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
3995         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
3996         AFTERWRITES=`count_ost_writes`
3997         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
3998                 error "$BEFOREWRITES < $AFTERWRITES"
3999         start_writeback
4000 }
4001 run_test 42a "ensure that we don't flush on close"
4002
4003 test_42b() {
4004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4005
4006         setup_test42
4007         cancel_lru_locks $OSC
4008         stop_writeback
4009         sync
4010         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4011         BEFOREWRITES=$(count_ost_writes)
4012         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4013         AFTERWRITES=$(count_ost_writes)
4014         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4015                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4016         fi
4017         BEFOREWRITES=$(count_ost_writes)
4018         sync || error "sync: $?"
4019         AFTERWRITES=$(count_ost_writes)
4020         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4021                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4022         fi
4023         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4024         start_writeback
4025         return 0
4026 }
4027 run_test 42b "test destroy of file with cached dirty data ======"
4028
4029 # if these tests just want to test the effect of truncation,
4030 # they have to be very careful.  consider:
4031 # - the first open gets a {0,EOF}PR lock
4032 # - the first write conflicts and gets a {0, count-1}PW
4033 # - the rest of the writes are under {count,EOF}PW
4034 # - the open for truncate tries to match a {0,EOF}PR
4035 #   for the filesize and cancels the PWs.
4036 # any number of fixes (don't get {0,EOF} on open, match
4037 # composite locks, do smarter file size management) fix
4038 # this, but for now we want these tests to verify that
4039 # the cancellation with truncate intent works, so we
4040 # start the file with a full-file pw lock to match against
4041 # until the truncate.
4042 trunc_test() {
4043         test=$1
4044         file=$DIR/$test
4045         offset=$2
4046         cancel_lru_locks $OSC
4047         stop_writeback
4048         # prime the file with 0,EOF PW to match
4049         touch $file
4050         $TRUNCATE $file 0
4051         sync; sync
4052         # now the real test..
4053         dd if=/dev/zero of=$file bs=1024 count=100
4054         BEFOREWRITES=`count_ost_writes`
4055         $TRUNCATE $file $offset
4056         cancel_lru_locks $OSC
4057         AFTERWRITES=`count_ost_writes`
4058         start_writeback
4059 }
4060
4061 test_42c() {
4062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4063
4064         trunc_test 42c 1024
4065         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4066                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4067         rm $file
4068 }
4069 run_test 42c "test partial truncate of file with cached dirty data"
4070
4071 test_42d() {
4072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4073
4074         trunc_test 42d 0
4075         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4076                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4077         rm $file
4078 }
4079 run_test 42d "test complete truncate of file with cached dirty data"
4080
4081 test_42e() { # bug22074
4082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4083
4084         local TDIR=$DIR/${tdir}e
4085         local pages=16 # hardcoded 16 pages, don't change it.
4086         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4087         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4088         local max_dirty_mb
4089         local warmup_files
4090
4091         test_mkdir $DIR/${tdir}e
4092         $LFS setstripe -c 1 $TDIR
4093         createmany -o $TDIR/f $files
4094
4095         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4096
4097         # we assume that with $OSTCOUNT files, at least one of them will
4098         # be allocated on OST0.
4099         warmup_files=$((OSTCOUNT * max_dirty_mb))
4100         createmany -o $TDIR/w $warmup_files
4101
4102         # write a large amount of data into one file and sync, to get good
4103         # avail_grant number from OST.
4104         for ((i=0; i<$warmup_files; i++)); do
4105                 idx=$($LFS getstripe -i $TDIR/w$i)
4106                 [ $idx -ne 0 ] && continue
4107                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4108                 break
4109         done
4110         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4111         sync
4112         $LCTL get_param $proc_osc0/cur_dirty_bytes
4113         $LCTL get_param $proc_osc0/cur_grant_bytes
4114
4115         # create as much dirty pages as we can while not to trigger the actual
4116         # RPCs directly. but depends on the env, VFS may trigger flush during this
4117         # period, hopefully we are good.
4118         for ((i=0; i<$warmup_files; i++)); do
4119                 idx=$($LFS getstripe -i $TDIR/w$i)
4120                 [ $idx -ne 0 ] && continue
4121                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4122         done
4123         $LCTL get_param $proc_osc0/cur_dirty_bytes
4124         $LCTL get_param $proc_osc0/cur_grant_bytes
4125
4126         # perform the real test
4127         $LCTL set_param $proc_osc0/rpc_stats 0
4128         for ((;i<$files; i++)); do
4129                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4130                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4131         done
4132         sync
4133         $LCTL get_param $proc_osc0/rpc_stats
4134
4135         local percent=0
4136         local have_ppr=false
4137         $LCTL get_param $proc_osc0/rpc_stats |
4138                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4139                         # skip lines until we are at the RPC histogram data
4140                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4141                         $have_ppr || continue
4142
4143                         # we only want the percent stat for < 16 pages
4144                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4145
4146                         percent=$((percent + WPCT))
4147                         if [[ $percent -gt 15 ]]; then
4148                                 error "less than 16-pages write RPCs" \
4149                                       "$percent% > 15%"
4150                                 break
4151                         fi
4152                 done
4153         rm -rf $TDIR
4154 }
4155 run_test 42e "verify sub-RPC writes are not done synchronously"
4156
4157 test_43A() { # was test_43
4158         test_mkdir $DIR/$tdir
4159         cp -p /bin/ls $DIR/$tdir/$tfile
4160         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4161         pid=$!
4162         # give multiop a chance to open
4163         sleep 1
4164
4165         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4166         kill -USR1 $pid
4167 }
4168 run_test 43A "execution of file opened for write should return -ETXTBSY"
4169
4170 test_43a() {
4171         test_mkdir $DIR/$tdir
4172         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4173         $DIR/$tdir/sleep 60 &
4174         SLEEP_PID=$!
4175         # Make sure exec of $tdir/sleep wins race with truncate
4176         sleep 1
4177         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4178         kill $SLEEP_PID
4179 }
4180 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4181
4182 test_43b() {
4183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4184
4185         test_mkdir $DIR/$tdir
4186         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4187         $DIR/$tdir/sleep 60 &
4188         SLEEP_PID=$!
4189         # Make sure exec of $tdir/sleep wins race with truncate
4190         sleep 1
4191         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4192         kill $SLEEP_PID
4193 }
4194 run_test 43b "truncate of file being executed should return -ETXTBSY"
4195
4196 test_43c() {
4197         local testdir="$DIR/$tdir"
4198         test_mkdir $testdir
4199         cp $SHELL $testdir/
4200         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4201                 ( cd $testdir && md5sum -c )
4202 }
4203 run_test 43c "md5sum of copy into lustre"
4204
4205 test_44A() { # was test_44
4206         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4207
4208         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4209         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4210 }
4211 run_test 44A "zero length read from a sparse stripe"
4212
4213 test_44a() {
4214         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4215                 awk '{ print $2 }')
4216         [ -z "$nstripe" ] && skip "can't get stripe info"
4217         [[ $nstripe -gt $OSTCOUNT ]] &&
4218                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4219
4220         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4221                 awk '{ print $2 }')
4222         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4223                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4224                         awk '{ print $2 }')
4225         fi
4226
4227         OFFSETS="0 $((stride/2)) $((stride-1))"
4228         for offset in $OFFSETS; do
4229                 for i in $(seq 0 $((nstripe-1))); do
4230                         local GLOBALOFFSETS=""
4231                         # size in Bytes
4232                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4233                         local myfn=$DIR/d44a-$size
4234                         echo "--------writing $myfn at $size"
4235                         ll_sparseness_write $myfn $size ||
4236                                 error "ll_sparseness_write"
4237                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4238                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4239                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4240
4241                         for j in $(seq 0 $((nstripe-1))); do
4242                                 # size in Bytes
4243                                 size=$((((j + $nstripe )*$stride + $offset)))
4244                                 ll_sparseness_write $myfn $size ||
4245                                         error "ll_sparseness_write"
4246                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4247                         done
4248                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4249                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4250                         rm -f $myfn
4251                 done
4252         done
4253 }
4254 run_test 44a "test sparse pwrite ==============================="
4255
4256 dirty_osc_total() {
4257         tot=0
4258         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4259                 tot=$(($tot + $d))
4260         done
4261         echo $tot
4262 }
4263 do_dirty_record() {
4264         before=`dirty_osc_total`
4265         echo executing "\"$*\""
4266         eval $*
4267         after=`dirty_osc_total`
4268         echo before $before, after $after
4269 }
4270 test_45() {
4271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4272
4273         f="$DIR/f45"
4274         # Obtain grants from OST if it supports it
4275         echo blah > ${f}_grant
4276         stop_writeback
4277         sync
4278         do_dirty_record "echo blah > $f"
4279         [[ $before -eq $after ]] && error "write wasn't cached"
4280         do_dirty_record "> $f"
4281         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4282         do_dirty_record "echo blah > $f"
4283         [[ $before -eq $after ]] && error "write wasn't cached"
4284         do_dirty_record "sync"
4285         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4286         do_dirty_record "echo blah > $f"
4287         [[ $before -eq $after ]] && error "write wasn't cached"
4288         do_dirty_record "cancel_lru_locks osc"
4289         [[ $before -gt $after ]] ||
4290                 error "lock cancellation didn't lower dirty count"
4291         start_writeback
4292 }
4293 run_test 45 "osc io page accounting ============================"
4294
4295 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4296 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4297 # objects offset and an assert hit when an rpc was built with 1023's mapped
4298 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4299 test_46() {
4300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4301
4302         f="$DIR/f46"
4303         stop_writeback
4304         sync
4305         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4306         sync
4307         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4308         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4309         sync
4310         start_writeback
4311 }
4312 run_test 46 "dirtying a previously written page ================"
4313
4314 # test_47 is removed "Device nodes check" is moved to test_28
4315
4316 test_48a() { # bug 2399
4317         [ "$mds1_FSTYPE" = "zfs" ] &&
4318         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4319                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4320
4321         test_mkdir $DIR/$tdir
4322         cd $DIR/$tdir
4323         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4324         test_mkdir $DIR/$tdir
4325         touch foo || error "'touch foo' failed after recreating cwd"
4326         test_mkdir bar
4327         touch .foo || error "'touch .foo' failed after recreating cwd"
4328         test_mkdir .bar
4329         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4330         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4331         cd . || error "'cd .' failed after recreating cwd"
4332         mkdir . && error "'mkdir .' worked after recreating cwd"
4333         rmdir . && error "'rmdir .' worked after recreating cwd"
4334         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4335         cd .. || error "'cd ..' failed after recreating cwd"
4336 }
4337 run_test 48a "Access renamed working dir (should return errors)="
4338
4339 test_48b() { # bug 2399
4340         rm -rf $DIR/$tdir
4341         test_mkdir $DIR/$tdir
4342         cd $DIR/$tdir
4343         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4344         touch foo && error "'touch foo' worked after removing cwd"
4345         mkdir foo && error "'mkdir foo' worked after removing cwd"
4346         touch .foo && error "'touch .foo' worked after removing cwd"
4347         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
4348         ls . > /dev/null && error "'ls .' worked after removing cwd"
4349         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4350         mkdir . && error "'mkdir .' worked after removing cwd"
4351         rmdir . && error "'rmdir .' worked after removing cwd"
4352         ln -s . foo && error "'ln -s .' worked after removing cwd"
4353         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
4354 }
4355 run_test 48b "Access removed working dir (should return errors)="
4356
4357 test_48c() { # bug 2350
4358         #lctl set_param debug=-1
4359         #set -vx
4360         rm -rf $DIR/$tdir
4361         test_mkdir -p $DIR/$tdir/dir
4362         cd $DIR/$tdir/dir
4363         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4364         $TRACE touch foo && error "touch foo worked after removing cwd"
4365         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
4366         touch .foo && error "touch .foo worked after removing cwd"
4367         mkdir .foo && error "mkdir .foo worked after removing cwd"
4368         $TRACE ls . && error "'ls .' worked after removing cwd"
4369         $TRACE ls .. || error "'ls ..' failed after removing cwd"
4370         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
4371         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
4372         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
4373         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
4374 }
4375 run_test 48c "Access removed working subdir (should return errors)"
4376
4377 test_48d() { # bug 2350
4378         #lctl set_param debug=-1
4379         #set -vx
4380         rm -rf $DIR/$tdir
4381         test_mkdir -p $DIR/$tdir/dir
4382         cd $DIR/$tdir/dir
4383         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4384         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4385         $TRACE touch foo && error "'touch foo' worked after removing parent"
4386         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
4387         touch .foo && error "'touch .foo' worked after removing parent"
4388         mkdir .foo && error "mkdir .foo worked after removing parent"
4389         $TRACE ls . && error "'ls .' worked after removing parent"
4390         $TRACE ls .. && error "'ls ..' worked after removing parent"
4391         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
4392         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
4393         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
4394         true
4395 }
4396 run_test 48d "Access removed parent subdir (should return errors)"
4397
4398 test_48e() { # bug 4134
4399         #lctl set_param debug=-1
4400         #set -vx
4401         rm -rf $DIR/$tdir
4402         test_mkdir -p $DIR/$tdir/dir
4403         cd $DIR/$tdir/dir
4404         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4405         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4406         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
4407         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
4408         # On a buggy kernel addition of "touch foo" after cd .. will
4409         # produce kernel oops in lookup_hash_it
4410         touch ../foo && error "'cd ..' worked after recreate parent"
4411         cd $DIR
4412         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
4413 }
4414 run_test 48e "Access to recreated parent subdir (should return errors)"
4415
4416 test_49() { # LU-1030
4417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4418         remote_ost_nodsh && skip "remote OST with nodsh"
4419
4420         # get ost1 size - lustre-OST0000
4421         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
4422                 awk '{ print $4 }')
4423         # write 800M at maximum
4424         [[ $ost1_size -lt 2 ]] && ost1_size=2
4425         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
4426
4427         $LFS setstripe -c 1 -i 0 $DIR/$tfile
4428         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
4429         local dd_pid=$!
4430
4431         # change max_pages_per_rpc while writing the file
4432         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
4433         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
4434         # loop until dd process exits
4435         while ps ax -opid | grep -wq $dd_pid; do
4436                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
4437                 sleep $((RANDOM % 5 + 1))
4438         done
4439         # restore original max_pages_per_rpc
4440         $LCTL set_param $osc1_mppc=$orig_mppc
4441         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
4442 }
4443 run_test 49 "Change max_pages_per_rpc won't break osc extent"
4444
4445 test_50() {
4446         # bug 1485
4447         test_mkdir $DIR/$tdir
4448         cd $DIR/$tdir
4449         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
4450 }
4451 run_test 50 "special situations: /proc symlinks  ==============="
4452
4453 test_51a() {    # was test_51
4454         # bug 1516 - create an empty entry right after ".." then split dir
4455         test_mkdir -c1 $DIR/$tdir
4456         touch $DIR/$tdir/foo
4457         $MCREATE $DIR/$tdir/bar
4458         rm $DIR/$tdir/foo
4459         createmany -m $DIR/$tdir/longfile 201
4460         FNUM=202
4461         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
4462                 $MCREATE $DIR/$tdir/longfile$FNUM
4463                 FNUM=$(($FNUM + 1))
4464                 echo -n "+"
4465         done
4466         echo
4467         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
4468 }
4469 run_test 51a "special situations: split htree with empty entry =="
4470
4471 cleanup_print_lfs_df () {
4472         trap 0
4473         $LFS df
4474         $LFS df -i
4475 }
4476
4477 test_51b() {
4478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4479
4480         local dir=$DIR/$tdir
4481         local nrdirs=$((65536 + 100))
4482
4483         # cleanup the directory
4484         rm -fr $dir
4485
4486         test_mkdir -c1 $dir
4487
4488         $LFS df
4489         $LFS df -i
4490         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
4491         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
4492         [[ $numfree -lt $nrdirs ]] &&
4493                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
4494
4495         # need to check free space for the directories as well
4496         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
4497         numfree=$(( blkfree / $(fs_inode_ksize) ))
4498         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
4499
4500         trap cleanup_print_lfs_df EXIT
4501
4502         # create files
4503         createmany -d $dir/d $nrdirs || {
4504                 unlinkmany $dir/d $nrdirs
4505                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
4506         }
4507
4508         # really created :
4509         nrdirs=$(ls -U $dir | wc -l)
4510
4511         # unlink all but 100 subdirectories, then check it still works
4512         local left=100
4513         local delete=$((nrdirs - left))
4514
4515         $LFS df
4516         $LFS df -i
4517
4518         # for ldiskfs the nlink count should be 1, but this is OSD specific
4519         # and so this is listed for informational purposes only
4520         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
4521         unlinkmany -d $dir/d $delete ||
4522                 error "unlink of first $delete subdirs failed"
4523
4524         echo "nlink between: $(stat -c %h $dir)"
4525         local found=$(ls -U $dir | wc -l)
4526         [ $found -ne $left ] &&
4527                 error "can't find subdirs: found only $found, expected $left"
4528
4529         unlinkmany -d $dir/d $delete $left ||
4530                 error "unlink of second $left subdirs failed"
4531         # regardless of whether the backing filesystem tracks nlink accurately
4532         # or not, the nlink count shouldn't be more than "." and ".." here
4533         local after=$(stat -c %h $dir)
4534         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
4535                 echo "nlink after: $after"
4536
4537         cleanup_print_lfs_df
4538 }
4539 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
4540
4541 test_51d() {
4542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4543         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
4544
4545         test_mkdir $DIR/$tdir
4546         createmany -o $DIR/$tdir/t- 1000
4547         $LFS getstripe $DIR/$tdir > $TMP/$tfile
4548         for N in $(seq 0 $((OSTCOUNT - 1))); do
4549                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
4550                         END { printf("%0.0f", objs) }' $TMP/$tfile)
4551                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
4552                         '($1 == '$N') { objs += 1 } \
4553                         END { printf("%0.0f", objs) }')
4554                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
4555         done
4556         unlinkmany $DIR/$tdir/t- 1000
4557
4558         NLAST=0
4559         for N in $(seq 1 $((OSTCOUNT - 1))); do
4560                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
4561                         error "OST $N has less objects vs OST $NLAST" \
4562                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4563                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
4564                         error "OST $N has less objects vs OST $NLAST" \
4565                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4566
4567                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
4568                         error "OST $N has less #0 objects vs OST $NLAST" \
4569                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4570                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
4571                         error "OST $N has less #0 objects vs OST $NLAST" \
4572                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4573                 NLAST=$N
4574         done
4575         rm -f $TMP/$tfile
4576 }
4577 run_test 51d "check object distribution"
4578
4579 test_51e() {
4580         if [ "$mds1_FSTYPE" != ldiskfs ]; then
4581                 skip_env "ldiskfs only test"
4582         fi
4583
4584         test_mkdir -c1 $DIR/$tdir
4585         test_mkdir -c1 $DIR/$tdir/d0
4586
4587         touch $DIR/$tdir/d0/foo
4588         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
4589                 error "file exceed 65000 nlink limit!"
4590         unlinkmany $DIR/$tdir/d0/f- 65001
4591         return 0
4592 }
4593 run_test 51e "check file nlink limit"
4594
4595 test_51f() {
4596         test_mkdir $DIR/$tdir
4597
4598         local max=100000
4599         local ulimit_old=$(ulimit -n)
4600         local spare=20 # number of spare fd's for scripts/libraries, etc.
4601         local mdt=$($LFS getstripe -m $DIR/$tdir)
4602         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
4603
4604         echo "MDT$mdt numfree=$numfree, max=$max"
4605         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
4606         if [ $((numfree + spare)) -gt $ulimit_old ]; then
4607                 while ! ulimit -n $((numfree + spare)); do
4608                         numfree=$((numfree * 3 / 4))
4609                 done
4610                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
4611         else
4612                 echo "left ulimit at $ulimit_old"
4613         fi
4614
4615         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
4616                 unlinkmany $DIR/$tdir/f $numfree
4617                 error "create+open $numfree files in $DIR/$tdir failed"
4618         }
4619         ulimit -n $ulimit_old
4620
4621         # if createmany exits at 120s there will be fewer than $numfree files
4622         unlinkmany $DIR/$tdir/f $numfree || true
4623 }
4624 run_test 51f "check many open files limit"
4625
4626 test_52a() {
4627         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
4628         test_mkdir $DIR/$tdir
4629         touch $DIR/$tdir/foo
4630         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
4631         echo bar >> $DIR/$tdir/foo || error "append bar failed"
4632         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
4633         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
4634         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
4635                                         error "link worked"
4636         echo foo >> $DIR/$tdir/foo || error "append foo failed"
4637         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
4638         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
4639                                                      error "lsattr"
4640         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
4641         cp -r $DIR/$tdir $TMP/
4642         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
4643 }
4644 run_test 52a "append-only flag test (should return errors)"
4645
4646 test_52b() {
4647         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
4648         test_mkdir $DIR/$tdir
4649         touch $DIR/$tdir/foo
4650         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
4651         cat test > $DIR/$tdir/foo && error "cat test worked"
4652         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
4653         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
4654         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
4655                                         error "link worked"
4656         echo foo >> $DIR/$tdir/foo && error "echo worked"
4657         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
4658         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
4659         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
4660         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
4661                                                         error "lsattr"
4662         chattr -i $DIR/$tdir/foo || error "chattr failed"
4663
4664         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
4665 }
4666 run_test 52b "immutable flag test (should return errors) ======="
4667
4668 test_53() {
4669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4670         remote_mds_nodsh && skip "remote MDS with nodsh"
4671         remote_ost_nodsh && skip "remote OST with nodsh"
4672
4673         local param
4674         local param_seq
4675         local ostname
4676         local mds_last
4677         local mds_last_seq
4678         local ost_last
4679         local ost_last_seq
4680         local ost_last_id
4681         local ostnum
4682         local node
4683         local found=false
4684         local support_last_seq=true
4685
4686         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
4687                 support_last_seq=false
4688
4689         # only test MDT0000
4690         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
4691         local value
4692         for value in $(do_facet $SINGLEMDS \
4693                        $LCTL get_param osc.$mdtosc.prealloc_last_id) ; do
4694                 param=$(echo ${value[0]} | cut -d "=" -f1)
4695                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
4696
4697                 if $support_last_seq; then
4698                         param_seq=$(echo $param |
4699                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
4700                         mds_last_seq=$(do_facet $SINGLEMDS \
4701                                        $LCTL get_param -n $param_seq)
4702                 fi
4703                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
4704
4705                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
4706                 node=$(facet_active_host ost$((ostnum+1)))
4707                 param="obdfilter.$ostname.last_id"
4708                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
4709                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
4710                         ost_last_id=$ost_last
4711
4712                         if $support_last_seq; then
4713                                 ost_last_id=$(echo $ost_last |
4714                                               awk -F':' '{print $2}' |
4715                                               sed -e "s/^0x//g")
4716                                 ost_last_seq=$(echo $ost_last |
4717                                                awk -F':' '{print $1}')
4718                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
4719                         fi
4720
4721                         if [[ $ost_last_id != $mds_last ]]; then
4722                                 error "$ost_last_id != $mds_last"
4723                         else
4724                                 found=true
4725                                 break
4726                         fi
4727                 done
4728         done
4729         $found || error "can not match last_seq/last_id for $mdtosc"
4730         return 0
4731 }
4732 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
4733
4734 test_54a() {
4735         perl -MSocket -e ';' || skip "no Socket perl module installed"
4736
4737         $SOCKETSERVER $DIR/socket ||
4738                 error "$SOCKETSERVER $DIR/socket failed: $?"
4739         $SOCKETCLIENT $DIR/socket ||
4740                 error "$SOCKETCLIENT $DIR/socket failed: $?"
4741         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
4742 }
4743 run_test 54a "unix domain socket test =========================="
4744
4745 test_54b() {
4746         f="$DIR/f54b"
4747         mknod $f c 1 3
4748         chmod 0666 $f
4749         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
4750 }
4751 run_test 54b "char device works in lustre ======================"
4752
4753 find_loop_dev() {
4754         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
4755         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
4756         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
4757
4758         for i in $(seq 3 7); do
4759                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
4760                 LOOPDEV=$LOOPBASE$i
4761                 LOOPNUM=$i
4762                 break
4763         done
4764 }
4765
4766 cleanup_54c() {
4767         local rc=0
4768         loopdev="$DIR/loop54c"
4769
4770         trap 0
4771         $UMOUNT $DIR/$tdir || rc=$?
4772         losetup -d $loopdev || true
4773         losetup -d $LOOPDEV || true
4774         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
4775         return $rc
4776 }
4777
4778 test_54c() {
4779         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4780
4781         loopdev="$DIR/loop54c"
4782
4783         find_loop_dev
4784         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
4785         trap cleanup_54c EXIT
4786         mknod $loopdev b 7 $LOOPNUM
4787         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
4788         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
4789         losetup $loopdev $DIR/$tfile ||
4790                 error "can't set up $loopdev for $DIR/$tfile"
4791         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
4792         test_mkdir $DIR/$tdir
4793         mount -t ext2 $loopdev $DIR/$tdir ||
4794                 error "error mounting $loopdev on $DIR/$tdir"
4795         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
4796                 error "dd write"
4797         df $DIR/$tdir
4798         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
4799                 error "dd read"
4800         cleanup_54c
4801 }
4802 run_test 54c "block device works in lustre ====================="
4803
4804 test_54d() {
4805         f="$DIR/f54d"
4806         string="aaaaaa"
4807         mknod $f p
4808         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
4809 }
4810 run_test 54d "fifo device works in lustre ======================"
4811
4812 test_54e() {
4813         f="$DIR/f54e"
4814         string="aaaaaa"
4815         cp -aL /dev/console $f
4816         echo $string > $f || error "echo $string to $f failed"
4817 }
4818 run_test 54e "console/tty device works in lustre ======================"
4819
4820 test_56a() {
4821         local numfiles=3
4822         local dir=$DIR/$tdir
4823
4824         rm -rf $dir
4825         test_mkdir -p $dir/dir
4826         for i in $(seq $numfiles); do
4827                 touch $dir/file$i
4828                 touch $dir/dir/file$i
4829         done
4830
4831         local numcomp=$($LFS getstripe --component-count $dir)
4832
4833         [[ $numcomp == 0 ]] && numcomp=1
4834
4835         # test lfs getstripe with --recursive
4836         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
4837
4838         [[ $filenum -eq $((numfiles * 2)) ]] ||
4839                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
4840         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
4841         [[ $filenum -eq $numfiles ]] ||
4842                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
4843         echo "$LFS getstripe showed obdidx or l_ost_idx"
4844
4845         # test lfs getstripe with file instead of dir
4846         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
4847         [[ $filenum -eq 1 ]] ||
4848                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
4849         echo "$LFS getstripe file1 passed"
4850
4851         #test lfs getstripe with --verbose
4852         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
4853         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
4854                 error "$LFS getstripe --verbose $dir: "\
4855                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
4856         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
4857                 error "$LFS getstripe $dir: showed lmm_magic"
4858
4859         #test lfs getstripe with -v prints lmm_fid
4860         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
4861         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
4862                 error "$LFS getstripe -v $dir: "\
4863                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
4864         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
4865                 error "$LFS getstripe $dir: showed lmm_fid by default"
4866         echo "$LFS getstripe --verbose passed"
4867
4868         #check for FID information
4869         local fid1=$($LFS getstripe --fid $dir/file1)
4870         local fid2=$($LFS getstripe --verbose $dir/file1 |
4871                      awk '/lmm_fid: / { print $2; exit; }')
4872         local fid3=$($LFS path2fid $dir/file1)
4873
4874         [ "$fid1" != "$fid2" ] &&
4875                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
4876         [ "$fid1" != "$fid3" ] &&
4877                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
4878         echo "$LFS getstripe --fid passed"
4879
4880         #test lfs getstripe with --obd
4881         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
4882                 error "$LFS getstripe --obd wrong_uuid: should return error"
4883
4884         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4885
4886         local ostidx=1
4887         local obduuid=$(ostuuid_from_index $ostidx)
4888         local found=$($LFS getstripe -r --obd $obduuid $dir |
4889                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
4890
4891         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
4892         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
4893                 ((filenum--))
4894         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
4895                 ((filenum--))
4896
4897         [[ $found -eq $filenum ]] ||
4898                 error "$LFS getstripe --obd: found $found expect $filenum"
4899         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
4900                 sed '/^[         ]*'${ostidx}'[  ]/d' |
4901                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
4902                 error "$LFS getstripe --obd: should not show file on other obd"
4903         echo "$LFS getstripe --obd passed"
4904 }
4905 run_test 56a "check $LFS getstripe"
4906
4907 test_56b() {
4908         local dir=$DIR/$tdir
4909         local numdirs=3
4910
4911         test_mkdir $dir
4912         for i in $(seq $numdirs); do
4913                 test_mkdir $dir/dir$i
4914         done
4915
4916         # test lfs getdirstripe default mode is non-recursion, which is
4917         # different from lfs getstripe
4918         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
4919
4920         [[ $dircnt -eq 1 ]] ||
4921                 error "$LFS getdirstripe: found $dircnt, not 1"
4922         dircnt=$($LFS getdirstripe --recursive $dir |
4923                 grep -c lmv_stripe_count)
4924         [[ $dircnt -eq $((numdirs + 1)) ]] ||
4925                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
4926 }
4927 run_test 56b "check $LFS getdirstripe"
4928
4929 test_56c() {
4930         remote_ost_nodsh && skip "remote OST with nodsh"
4931
4932         local ost_idx=0
4933         local ost_name=$(ostname_from_index $ost_idx)
4934         local old_status=$(ost_dev_status $ost_idx)
4935
4936         [[ -z "$old_status" ]] ||
4937                 skip_env "OST $ost_name is in $old_status status"
4938
4939         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
4940         sleep_maxage
4941
4942         local new_status=$(ost_dev_status $ost_idx)
4943
4944         [[ "$new_status" = "D" ]] ||
4945                 error "OST $ost_name is in status of '$new_status', not 'D'"
4946
4947         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
4948         sleep_maxage
4949
4950         new_status=$(ost_dev_status $ost_idx)
4951         [[ -z "$new_status" ]] ||
4952                 error "OST $ost_name is in status of '$new_status', not ''"
4953 }
4954 run_test 56c "check 'lfs df' showing device status"
4955
4956 NUMFILES=3
4957 NUMDIRS=3
4958 setup_56() {
4959         local local_tdir="$1"
4960         local local_numfiles="$2"
4961         local local_numdirs="$3"
4962         local dir_params="$4"
4963         local dir_stripe_params="$5"
4964
4965         if [ ! -d "$local_tdir" ] ; then
4966                 test_mkdir -p $dir_stripe_params $local_tdir
4967                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
4968                 for i in $(seq $local_numfiles) ; do
4969                         touch $local_tdir/file$i
4970                 done
4971                 for i in $(seq $local_numdirs) ; do
4972                         test_mkdir $dir_stripe_params $local_tdir/dir$i
4973                         for j in $(seq $local_numfiles) ; do
4974                                 touch $local_tdir/dir$i/file$j
4975                         done
4976                 done
4977         fi
4978 }
4979
4980 setup_56_special() {
4981         local local_tdir=$1
4982         local local_numfiles=$2
4983         local local_numdirs=$3
4984
4985         setup_56 $local_tdir $local_numfiles $local_numdirs
4986
4987         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
4988                 for i in $(seq $local_numfiles) ; do
4989                         mknod $local_tdir/loop${i}b b 7 $i
4990                         mknod $local_tdir/null${i}c c 1 3
4991                         ln -s $local_tdir/file1 $local_tdir/link${i}
4992                 done
4993                 for i in $(seq $local_numdirs) ; do
4994                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
4995                         mknod $local_tdir/dir$i/null${i}c c 1 3
4996                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
4997                 done
4998         fi
4999 }
5000
5001 test_56g() {
5002         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5003         local expected=$(($NUMDIRS + 2))
5004
5005         setup_56 $dir $NUMFILES $NUMDIRS
5006
5007         # test lfs find with -name
5008         for i in $(seq $NUMFILES) ; do
5009                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5010
5011                 [ $nums -eq $expected ] ||
5012                         error "lfs find -name '*$i' $dir wrong: "\
5013                               "found $nums, expected $expected"
5014         done
5015 }
5016 run_test 56g "check lfs find -name"
5017
5018 test_56h() {
5019         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5020         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5021
5022         setup_56 $dir $NUMFILES $NUMDIRS
5023
5024         # test lfs find with ! -name
5025         for i in $(seq $NUMFILES) ; do
5026                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5027
5028                 [ $nums -eq $expected ] ||
5029                         error "lfs find ! -name '*$i' $dir wrong: "\
5030                               "found $nums, expected $expected"
5031         done
5032 }
5033 run_test 56h "check lfs find ! -name"
5034
5035 test_56i() {
5036         local dir=$DIR/$tdir
5037
5038         test_mkdir $dir
5039
5040         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5041         local out=$($cmd)
5042
5043         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5044 }
5045 run_test 56i "check 'lfs find -ost UUID' skips directories"
5046
5047 test_56j() {
5048         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5049
5050         setup_56_special $dir $NUMFILES $NUMDIRS
5051
5052         local expected=$((NUMDIRS + 1))
5053         local cmd="$LFS find -type d $dir"
5054         local nums=$($cmd | wc -l)
5055
5056         [ $nums -eq $expected ] ||
5057                 error "'$cmd' wrong: found $nums, expected $expected"
5058 }
5059 run_test 56j "check lfs find -type d"
5060
5061 test_56k() {
5062         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5063
5064         setup_56_special $dir $NUMFILES $NUMDIRS
5065
5066         local expected=$(((NUMDIRS + 1) * NUMFILES))
5067         local cmd="$LFS find -type f $dir"
5068         local nums=$($cmd | wc -l)
5069
5070         [ $nums -eq $expected ] ||
5071                 error "'$cmd' wrong: found $nums, expected $expected"
5072 }
5073 run_test 56k "check lfs find -type f"
5074
5075 test_56l() {
5076         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5077
5078         setup_56_special $dir $NUMFILES $NUMDIRS
5079
5080         local expected=$((NUMDIRS + NUMFILES))
5081         local cmd="$LFS find -type b $dir"
5082         local nums=$($cmd | wc -l)
5083
5084         [ $nums -eq $expected ] ||
5085                 error "'$cmd' wrong: found $nums, expected $expected"
5086 }
5087 run_test 56l "check lfs find -type b"
5088
5089 test_56m() {
5090         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5091
5092         setup_56_special $dir $NUMFILES $NUMDIRS
5093
5094         local expected=$((NUMDIRS + NUMFILES))
5095         local cmd="$LFS find -type c $dir"
5096         local nums=$($cmd | wc -l)
5097         [ $nums -eq $expected ] ||
5098                 error "'$cmd' wrong: found $nums, expected $expected"
5099 }
5100 run_test 56m "check lfs find -type c"
5101
5102 test_56n() {
5103         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5104         setup_56_special $dir $NUMFILES $NUMDIRS
5105
5106         local expected=$((NUMDIRS + NUMFILES))
5107         local cmd="$LFS find -type l $dir"
5108         local nums=$($cmd | wc -l)
5109
5110         [ $nums -eq $expected ] ||
5111                 error "'$cmd' wrong: found $nums, expected $expected"
5112 }
5113 run_test 56n "check lfs find -type l"
5114
5115 test_56o() {
5116         local dir=$DIR/$tdir
5117
5118         setup_56 $dir $NUMFILES $NUMDIRS
5119         utime $dir/file1 > /dev/null || error "utime (1)"
5120         utime $dir/file2 > /dev/null || error "utime (2)"
5121         utime $dir/dir1 > /dev/null || error "utime (3)"
5122         utime $dir/dir2 > /dev/null || error "utime (4)"
5123         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5124         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5125
5126         local expected=4
5127         local nums=$($LFS find -mtime +0 $dir | wc -l)
5128
5129         [ $nums -eq $expected ] ||
5130                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5131
5132         expected=12
5133         cmd="$LFS find -mtime 0 $dir"
5134         nums=$($cmd | wc -l)
5135         [ $nums -eq $expected ] ||
5136                 error "'$cmd' wrong: found $nums, expected $expected"
5137 }
5138 run_test 56o "check lfs find -mtime for old files"
5139
5140 test_56ob() {
5141         local dir=$DIR/$tdir
5142         local expected=1
5143         local count=0
5144
5145         # just to make sure there is something that won't be found
5146         test_mkdir $dir
5147         touch $dir/$tfile.now
5148
5149         for age in year week day hour min; do
5150                 count=$((count + 1))
5151
5152                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5153                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5154                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5155
5156                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5157                 local nums=$($cmd | wc -l)
5158                 [ $nums -eq $expected ] ||
5159                         error "'$cmd' wrong: found $nums, expected $expected"
5160
5161                 cmd="$LFS find $dir -atime $count${age:0:1}"
5162                 nums=$($cmd | wc -l)
5163                 [ $nums -eq $expected ] ||
5164                         error "'$cmd' wrong: found $nums, expected $expected"
5165         done
5166
5167         sleep 2
5168         cmd="$LFS find $dir -ctime +1s -type f"
5169         nums=$($cmd | wc -l)
5170         (( $nums == $count * 2 + 1)) ||
5171                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5172 }
5173 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5174
5175 test_56p() {
5176         [ $RUNAS_ID -eq $UID ] &&
5177                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5178
5179         local dir=$DIR/$tdir
5180
5181         setup_56 $dir $NUMFILES $NUMDIRS
5182         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5183
5184         local expected=$NUMFILES
5185         local cmd="$LFS find -uid $RUNAS_ID $dir"
5186         local nums=$($cmd | wc -l)
5187
5188         [ $nums -eq $expected ] ||
5189                 error "'$cmd' wrong: found $nums, expected $expected"
5190
5191         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5192         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5193         nums=$($cmd | wc -l)
5194         [ $nums -eq $expected ] ||
5195                 error "'$cmd' wrong: found $nums, expected $expected"
5196 }
5197 run_test 56p "check lfs find -uid and ! -uid"
5198
5199 test_56q() {
5200         [ $RUNAS_ID -eq $UID ] &&
5201                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5202
5203         local dir=$DIR/$tdir
5204
5205         setup_56 $dir $NUMFILES $NUMDIRS
5206         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5207
5208         local expected=$NUMFILES
5209         local cmd="$LFS find -gid $RUNAS_GID $dir"
5210         local nums=$($cmd | wc -l)
5211
5212         [ $nums -eq $expected ] ||
5213                 error "'$cmd' wrong: found $nums, expected $expected"
5214
5215         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5216         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5217         nums=$($cmd | wc -l)
5218         [ $nums -eq $expected ] ||
5219                 error "'$cmd' wrong: found $nums, expected $expected"
5220 }
5221 run_test 56q "check lfs find -gid and ! -gid"
5222
5223 test_56r() {
5224         local dir=$DIR/$tdir
5225
5226         setup_56 $dir $NUMFILES $NUMDIRS
5227
5228         local expected=12
5229         local cmd="$LFS find -size 0 -type f $dir"
5230         local nums=$($cmd | wc -l)
5231
5232         [ $nums -eq $expected ] ||
5233                 error "'$cmd' wrong: found $nums, expected $expected"
5234         expected=0
5235         cmd="$LFS find ! -size 0 -type f $dir"
5236         nums=$($cmd | wc -l)
5237         [ $nums -eq $expected ] ||
5238                 error "'$cmd' wrong: found $nums, expected $expected"
5239         echo "test" > $dir/$tfile
5240         echo "test2" > $dir/$tfile.2 && sync
5241         expected=1
5242         cmd="$LFS find -size 5 -type f $dir"
5243         nums=$($cmd | wc -l)
5244         [ $nums -eq $expected ] ||
5245                 error "'$cmd' wrong: found $nums, expected $expected"
5246         expected=1
5247         cmd="$LFS find -size +5 -type f $dir"
5248         nums=$($cmd | wc -l)
5249         [ $nums -eq $expected ] ||
5250                 error "'$cmd' wrong: found $nums, expected $expected"
5251         expected=2
5252         cmd="$LFS find -size +0 -type f $dir"
5253         nums=$($cmd | wc -l)
5254         [ $nums -eq $expected ] ||
5255                 error "'$cmd' wrong: found $nums, expected $expected"
5256         expected=2
5257         cmd="$LFS find ! -size -5 -type f $dir"
5258         nums=$($cmd | wc -l)
5259         [ $nums -eq $expected ] ||
5260                 error "'$cmd' wrong: found $nums, expected $expected"
5261         expected=12
5262         cmd="$LFS find -size -5 -type f $dir"
5263         nums=$($cmd | wc -l)
5264         [ $nums -eq $expected ] ||
5265                 error "'$cmd' wrong: found $nums, expected $expected"
5266 }
5267 run_test 56r "check lfs find -size works"
5268
5269 test_56s() { # LU-611 #LU-9369
5270         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
5271
5272         local dir=$DIR/$tdir
5273         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
5274
5275         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
5276         for i in $(seq $NUMDIRS); do
5277                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
5278         done
5279
5280         local expected=$NUMDIRS
5281         local cmd="$LFS find -c $OSTCOUNT $dir"
5282         local nums=$($cmd | wc -l)
5283
5284         [ $nums -eq $expected ] || {
5285                 $LFS getstripe -R $dir
5286                 error "'$cmd' wrong: found $nums, expected $expected"
5287         }
5288
5289         expected=$((NUMDIRS + onestripe))
5290         cmd="$LFS find -stripe-count +0 -type f $dir"
5291         nums=$($cmd | wc -l)
5292         [ $nums -eq $expected ] || {
5293                 $LFS getstripe -R $dir
5294                 error "'$cmd' wrong: found $nums, expected $expected"
5295         }
5296
5297         expected=$onestripe
5298         cmd="$LFS find -stripe-count 1 -type f $dir"
5299         nums=$($cmd | wc -l)
5300         [ $nums -eq $expected ] || {
5301                 $LFS getstripe -R $dir
5302                 error "'$cmd' wrong: found $nums, expected $expected"
5303         }
5304
5305         cmd="$LFS find -stripe-count -2 -type f $dir"
5306         nums=$($cmd | wc -l)
5307         [ $nums -eq $expected ] || {
5308                 $LFS getstripe -R $dir
5309                 error "'$cmd' wrong: found $nums, expected $expected"
5310         }
5311
5312         expected=0
5313         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
5314         nums=$($cmd | wc -l)
5315         [ $nums -eq $expected ] || {
5316                 $LFS getstripe -R $dir
5317                 error "'$cmd' wrong: found $nums, expected $expected"
5318         }
5319 }
5320 run_test 56s "check lfs find -stripe-count works"
5321
5322 test_56t() { # LU-611 #LU-9369
5323         local dir=$DIR/$tdir
5324
5325         setup_56 $dir 0 $NUMDIRS
5326         for i in $(seq $NUMDIRS); do
5327                 $LFS setstripe -S 8M $dir/dir$i/$tfile
5328         done
5329
5330         local expected=$NUMDIRS
5331         local cmd="$LFS find -S 8M $dir"
5332         local nums=$($cmd | wc -l)
5333
5334         [ $nums -eq $expected ] || {
5335                 $LFS getstripe -R $dir
5336                 error "'$cmd' wrong: found $nums, expected $expected"
5337         }
5338         rm -rf $dir
5339
5340         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
5341
5342         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
5343
5344         expected=$(((NUMDIRS + 1) * NUMFILES))
5345         cmd="$LFS find -stripe-size 512k -type f $dir"
5346         nums=$($cmd | wc -l)
5347         [ $nums -eq $expected ] ||
5348                 error "'$cmd' wrong: found $nums, expected $expected"
5349
5350         cmd="$LFS find -stripe-size +320k -type f $dir"
5351         nums=$($cmd | wc -l)
5352         [ $nums -eq $expected ] ||
5353                 error "'$cmd' wrong: found $nums, expected $expected"
5354
5355         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
5356         cmd="$LFS find -stripe-size +200k -type f $dir"
5357         nums=$($cmd | wc -l)
5358         [ $nums -eq $expected ] ||
5359                 error "'$cmd' wrong: found $nums, expected $expected"
5360
5361         cmd="$LFS find -stripe-size -640k -type f $dir"
5362         nums=$($cmd | wc -l)
5363         [ $nums -eq $expected ] ||
5364                 error "'$cmd' wrong: found $nums, expected $expected"
5365
5366         expected=4
5367         cmd="$LFS find -stripe-size 256k -type f $dir"
5368         nums=$($cmd | wc -l)
5369         [ $nums -eq $expected ] ||
5370                 error "'$cmd' wrong: found $nums, expected $expected"
5371
5372         cmd="$LFS find -stripe-size -320k -type f $dir"
5373         nums=$($cmd | wc -l)
5374         [ $nums -eq $expected ] ||
5375                 error "'$cmd' wrong: found $nums, expected $expected"
5376
5377         expected=0
5378         cmd="$LFS find -stripe-size 1024k -type f $dir"
5379         nums=$($cmd | wc -l)
5380         [ $nums -eq $expected ] ||
5381                 error "'$cmd' wrong: found $nums, expected $expected"
5382 }
5383 run_test 56t "check lfs find -stripe-size works"
5384
5385 test_56u() { # LU-611
5386         local dir=$DIR/$tdir
5387
5388         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
5389
5390         if [[ $OSTCOUNT -gt 1 ]]; then
5391                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
5392                 onestripe=4
5393         else
5394                 onestripe=0
5395         fi
5396
5397         local expected=$(((NUMDIRS + 1) * NUMFILES))
5398         local cmd="$LFS find -stripe-index 0 -type f $dir"
5399         local nums=$($cmd | wc -l)
5400
5401         [ $nums -eq $expected ] ||
5402                 error "'$cmd' wrong: found $nums, expected $expected"
5403
5404         expected=$onestripe
5405         cmd="$LFS find -stripe-index 1 -type f $dir"
5406         nums=$($cmd | wc -l)
5407         [ $nums -eq $expected ] ||
5408                 error "'$cmd' wrong: found $nums, expected $expected"
5409
5410         cmd="$LFS find ! -stripe-index 0 -type f $dir"
5411         nums=$($cmd | wc -l)
5412         [ $nums -eq $expected ] ||
5413                 error "'$cmd' wrong: found $nums, expected $expected"
5414
5415         expected=0
5416         # This should produce an error and not return any files
5417         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
5418         nums=$($cmd 2>/dev/null | wc -l)
5419         [ $nums -eq $expected ] ||
5420                 error "'$cmd' wrong: found $nums, expected $expected"
5421
5422         if [[ $OSTCOUNT -gt 1 ]]; then
5423                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
5424                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
5425                 nums=$($cmd | wc -l)
5426                 [ $nums -eq $expected ] ||
5427                         error "'$cmd' wrong: found $nums, expected $expected"
5428         fi
5429 }
5430 run_test 56u "check lfs find -stripe-index works"
5431
5432 test_56v() {
5433         local mdt_idx=0
5434         local dir=$DIR/$tdir
5435
5436         setup_56 $dir $NUMFILES $NUMDIRS
5437
5438         UUID=$(mdtuuid_from_index $mdt_idx $dir)
5439         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
5440
5441         for file in $($LFS find -m $UUID $dir); do
5442                 file_midx=$($LFS getstripe -m $file)
5443                 [ $file_midx -eq $mdt_idx ] ||
5444                         error "lfs find -m $UUID != getstripe -m $file_midx"
5445         done
5446 }
5447 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
5448
5449 test_56w() {
5450         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5452
5453         local dir=$DIR/$tdir
5454
5455         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
5456
5457         local stripe_size=$($LFS getstripe -S -d $dir) ||
5458                 error "$LFS getstripe -S -d $dir failed"
5459         stripe_size=${stripe_size%% *}
5460
5461         local file_size=$((stripe_size * OSTCOUNT))
5462         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
5463         local required_space=$((file_num * file_size))
5464         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
5465                            head -n1)
5466         [[ $free_space -le $((required_space / 1024)) ]] &&
5467                 skip_env "need $required_space, have $free_space kbytes"
5468
5469         local dd_bs=65536
5470         local dd_count=$((file_size / dd_bs))
5471
5472         # write data into the files
5473         local i
5474         local j
5475         local file
5476
5477         for i in $(seq $NUMFILES); do
5478                 file=$dir/file$i
5479                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5480                         error "write data into $file failed"
5481         done
5482         for i in $(seq $NUMDIRS); do
5483                 for j in $(seq $NUMFILES); do
5484                         file=$dir/dir$i/file$j
5485                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5486                                 error "write data into $file failed"
5487                 done
5488         done
5489
5490         # $LFS_MIGRATE will fail if hard link migration is unsupported
5491         if [[ $(lustre_version_code mds1) -gt $(version_code 2.5.55) ]]; then
5492                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
5493                         error "creating links to $dir/dir1/file1 failed"
5494         fi
5495
5496         local expected=-1
5497
5498         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
5499
5500         # lfs_migrate file
5501         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
5502
5503         echo "$cmd"
5504         eval $cmd || error "$cmd failed"
5505
5506         check_stripe_count $dir/file1 $expected
5507
5508         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
5509         then
5510                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
5511                 # OST 1 if it is on OST 0. This file is small enough to
5512                 # be on only one stripe.
5513                 file=$dir/migr_1_ost
5514                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
5515                         error "write data into $file failed"
5516                 local obdidx=$($LFS getstripe -i $file)
5517                 local oldmd5=$(md5sum $file)
5518                 local newobdidx=0
5519
5520                 [[ $obdidx -eq 0 ]] && newobdidx=1
5521                 cmd="$LFS migrate -i $newobdidx $file"
5522                 echo $cmd
5523                 eval $cmd || error "$cmd failed"
5524
5525                 local realobdix=$($LFS getstripe -i $file)
5526                 local newmd5=$(md5sum $file)
5527
5528                 [[ $newobdidx -ne $realobdix ]] &&
5529                         error "new OST is different (was=$obdidx, "\
5530                               "wanted=$newobdidx, got=$realobdix)"
5531                 [[ "$oldmd5" != "$newmd5" ]] &&
5532                         error "md5sum differ: $oldmd5, $newmd5"
5533         fi
5534
5535         # lfs_migrate dir
5536         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
5537         echo "$cmd"
5538         eval $cmd || error "$cmd failed"
5539
5540         for j in $(seq $NUMFILES); do
5541                 check_stripe_count $dir/dir1/file$j $expected
5542         done
5543
5544         # lfs_migrate works with lfs find
5545         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
5546              $LFS_MIGRATE -y -c $expected"
5547         echo "$cmd"
5548         eval $cmd || error "$cmd failed"
5549
5550         for i in $(seq 2 $NUMFILES); do
5551                 check_stripe_count $dir/file$i $expected
5552         done
5553         for i in $(seq 2 $NUMDIRS); do
5554                 for j in $(seq $NUMFILES); do
5555                 check_stripe_count $dir/dir$i/file$j $expected
5556                 done
5557         done
5558 }
5559 run_test 56w "check lfs_migrate -c stripe_count works"
5560
5561 test_56wb() {
5562         local file1=$DIR/$tdir/file1
5563         local create_pool=false
5564         local initial_pool=$($LFS getstripe -p $DIR)
5565         local pool_list=()
5566         local pool=""
5567
5568         echo -n "Creating test dir..."
5569         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5570         echo "done."
5571
5572         echo -n "Creating test file..."
5573         touch $file1 || error "cannot create file"
5574         echo "done."
5575
5576         echo -n "Detecting existing pools..."
5577         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
5578
5579         if [ ${#pool_list[@]} -gt 0 ]; then
5580                 echo "${pool_list[@]}"
5581                 for thispool in "${pool_list[@]}"; do
5582                         if [[ -z "$initial_pool" ||
5583                               "$initial_pool" != "$thispool" ]]; then
5584                                 pool="$thispool"
5585                                 echo "Using existing pool '$pool'"
5586                                 break
5587                         fi
5588                 done
5589         else
5590                 echo "none detected."
5591         fi
5592         if [ -z "$pool" ]; then
5593                 pool=${POOL:-testpool}
5594                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
5595                 echo -n "Creating pool '$pool'..."
5596                 create_pool=true
5597                 pool_add $pool &> /dev/null ||
5598                         error "pool_add failed"
5599                 echo "done."
5600
5601                 echo -n "Adding target to pool..."
5602                 pool_add_targets $pool 0 0 1 &> /dev/null ||
5603                         error "pool_add_targets failed"
5604                 echo "done."
5605         fi
5606
5607         echo -n "Setting pool using -p option..."
5608         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
5609                 error "migrate failed rc = $?"
5610         echo "done."
5611
5612         echo -n "Verifying test file is in pool after migrating..."
5613         [ "$($LFS getstripe -p $file1)" = $pool ] ||
5614                 error "file was not migrated to pool $pool"
5615         echo "done."
5616
5617         echo -n "Removing test file from pool '$pool'..."
5618         $LFS migrate $file1 &> /dev/null ||
5619                 error "cannot remove from pool"
5620         [ "$($LFS getstripe -p $file1)" ] &&
5621                 error "pool still set"
5622         echo "done."
5623
5624         echo -n "Setting pool using --pool option..."
5625         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
5626                 error "migrate failed rc = $?"
5627         echo "done."
5628
5629         # Clean up
5630         rm -f $file1
5631         if $create_pool; then
5632                 destroy_test_pools 2> /dev/null ||
5633                         error "destroy test pools failed"
5634         fi
5635 }
5636 run_test 56wb "check lfs_migrate pool support"
5637
5638 test_56wc() {
5639         local file1="$DIR/$tdir/file1"
5640
5641         echo -n "Creating test dir..."
5642         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5643         local def_stripe_size=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
5644         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
5645                 error "cannot set stripe"
5646         echo "done"
5647
5648         echo -n "Setting initial stripe for test file..."
5649         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
5650                 error "cannot set stripe"
5651         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
5652                 error "stripe size not set"
5653         echo "done."
5654
5655         # File currently set to -S 512K -c 1
5656
5657         # Ensure -c and -S options are rejected when -R is set
5658         echo -n "Verifying incompatible options are detected..."
5659         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
5660                 error "incompatible -c and -R options not detected"
5661         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
5662                 error "incompatible -S and -R options not detected"
5663         echo "done."
5664
5665         # Ensure unrecognized options are passed through to 'lfs migrate'
5666         echo -n "Verifying -S option is passed through to lfs migrate..."
5667         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
5668                 error "migration failed"
5669         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
5670                 error "file was not restriped"
5671         echo "done."
5672
5673         # File currently set to -S 1M -c 1
5674
5675         # Ensure long options are supported
5676         echo -n "Verifying long options supported..."
5677         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
5678                 error "long option without argument not supported"
5679         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
5680                 error "long option with argument not supported"
5681         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
5682                 error "file not restriped with --stripe-size option"
5683         echo "done."
5684
5685         # File currently set to -S 512K -c 1
5686
5687         if [ "$OSTCOUNT" -gt 1 ]; then
5688                 echo -n "Verifying explicit stripe count can be set..."
5689                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
5690                         error "migrate failed"
5691                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
5692                         error "file not restriped to explicit count"
5693                 echo "done."
5694         fi
5695
5696         # File currently set to -S 512K -c 1 or -S 512K -c 2
5697
5698         # Ensure parent striping is used if -R is set, and no stripe
5699         # count or size is specified
5700         echo -n "Setting stripe for parent directory..."
5701         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
5702                 error "cannot set stripe"
5703         echo "done."
5704
5705         echo -n "Verifying restripe option uses parent stripe settings..."
5706         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
5707                 error "migrate failed"
5708         [ $($LFS getstripe -S "$file1") -eq $def_stripe_size ] ||
5709                 error "file not restriped to parent settings"
5710         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
5711                 error "file not restriped to parent settings"
5712         echo "done."
5713
5714         # File currently set to -S 1M -c 1
5715
5716         # Ensure striping is preserved if -R is not set, and no stripe
5717         # count or size is specified
5718         echo -n "Verifying striping size preserved when not specified..."
5719         local orig_stripe_size=$($LFS getstripe -S "$file1" 2>/dev/null)
5720         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
5721                 error "cannot set stripe on parent directory"
5722         $LFS_MIGRATE -y "$file1" &> /dev/null ||
5723                 error "migrate failed"
5724         [ $($LFS getstripe -S "$file1") -eq $orig_stripe_size ] ||
5725                 error "file was restriped"
5726         echo "done."
5727
5728         # Ensure file name properly detected when final option has no argument
5729         echo -n "Verifying file name properly detected..."
5730         $LFS_MIGRATE -y "$file1" &> /dev/null ||
5731                 error "file name interpreted as option argument"
5732         echo "done."
5733
5734         # Clean up
5735         rm -f "$file1"
5736 }
5737 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
5738
5739 test_56wd() {
5740         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5741
5742         local file1=$DIR/$tdir/file1
5743
5744         echo -n "Creating test dir..."
5745         test_mkdir $DIR/$tdir || error "cannot create dir"
5746         echo "done."
5747
5748         echo -n "Creating test file..."
5749         touch $file1
5750         echo "done."
5751
5752         # Ensure 'lfs migrate' will fail by using a non-existent option,
5753         # and make sure rsync is not called to recover
5754         echo -n "Make sure --no-rsync option works..."
5755         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
5756                 grep -q 'refusing to fall back to rsync' ||
5757                 error "rsync was called with --no-rsync set"
5758         echo "done."
5759
5760         # Ensure rsync is called without trying 'lfs migrate' first
5761         echo -n "Make sure --rsync option works..."
5762         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
5763                 grep -q 'falling back to rsync' &&
5764                 error "lfs migrate was called with --rsync set"
5765         echo "done."
5766
5767         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
5768         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
5769                 grep -q 'at the same time' ||
5770                 error "--rsync and --no-rsync accepted concurrently"
5771         echo "done."
5772
5773         # Clean up
5774         rm -f $file1
5775 }
5776 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
5777
5778 test_56x() {
5779         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5780         check_swap_layouts_support
5781
5782         local dir=$DIR/$tdir
5783         local ref1=/etc/passwd
5784         local file1=$dir/file1
5785
5786         test_mkdir $dir || error "creating dir $dir"
5787         $LFS setstripe -c 2 $file1
5788         cp $ref1 $file1
5789         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
5790         stripe=$($LFS getstripe -c $file1)
5791         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
5792         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
5793
5794         # clean up
5795         rm -f $file1
5796 }
5797 run_test 56x "lfs migration support"
5798
5799 test_56xa() {
5800         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5801         check_swap_layouts_support
5802
5803         local dir=$DIR/$tdir/$testnum
5804
5805         test_mkdir -p $dir
5806
5807         local ref1=/etc/passwd
5808         local file1=$dir/file1
5809
5810         $LFS setstripe -c 2 $file1
5811         cp $ref1 $file1
5812         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
5813
5814         local stripe=$($LFS getstripe -c $file1)
5815
5816         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
5817         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
5818
5819         # clean up
5820         rm -f $file1
5821 }
5822 run_test 56xa "lfs migration --block support"
5823
5824 check_migrate_links() {
5825         local dir="$1"
5826         local file1="$dir/file1"
5827         local begin="$2"
5828         local count="$3"
5829         local total_count=$(($begin + $count - 1))
5830         local symlink_count=10
5831         local uniq_count=10
5832
5833         if [ ! -f "$file1" ]; then
5834                 echo -n "creating initial file..."
5835                 $LFS setstripe -c 1 -S "512k" "$file1" ||
5836                         error "cannot setstripe initial file"
5837                 echo "done"
5838
5839                 echo -n "creating symlinks..."
5840                 for s in $(seq 1 $symlink_count); do
5841                         ln -s "$file1" "$dir/slink$s" ||
5842                                 error "cannot create symlinks"
5843                 done
5844                 echo "done"
5845
5846                 echo -n "creating nonlinked files..."
5847                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
5848                         error "cannot create nonlinked files"
5849                 echo "done"
5850         fi
5851
5852         # create hard links
5853         if [ ! -f "$dir/file$total_count" ]; then
5854                 echo -n "creating hard links $begin:$total_count..."
5855                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
5856                         /dev/null || error "cannot create hard links"
5857                 echo "done"
5858         fi
5859
5860         echo -n "checking number of hard links listed in xattrs..."
5861         local fid=$($LFS getstripe -F "$file1")
5862         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
5863
5864         echo "${#paths[*]}"
5865         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
5866                         skip "hard link list has unexpected size, skipping test"
5867         fi
5868         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
5869                         error "link names should exceed xattrs size"
5870         fi
5871
5872         echo -n "migrating files..."
5873         local migrate_out=$($LFS_MIGRATE -y -S '1m' $dir)
5874         local rc=$?
5875         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
5876         echo "done"
5877
5878         # make sure all links have been properly migrated
5879         echo -n "verifying files..."
5880         fid=$($LFS getstripe -F "$file1") ||
5881                 error "cannot get fid for file $file1"
5882         for i in $(seq 2 $total_count); do
5883                 local fid2=$($LFS getstripe -F $dir/file$i)
5884
5885                 [ "$fid2" == "$fid" ] ||
5886                         error "migrated hard link has mismatched FID"
5887         done
5888
5889         # make sure hard links were properly detected, and migration was
5890         # performed only once for the entire link set; nonlinked files should
5891         # also be migrated
5892         local actual=$(grep -c 'done migrate' <<< "$migrate_out")
5893         local expected=$(($uniq_count + 1))
5894
5895         [ "$actual" -eq  "$expected" ] ||
5896                 error "hard links individually migrated ($actual != $expected)"
5897
5898         # make sure the correct number of hard links are present
5899         local hardlinks=$(stat -c '%h' "$file1")
5900
5901         [ $hardlinks -eq $total_count ] ||
5902                 error "num hard links $hardlinks != $total_count"
5903         echo "done"
5904
5905         return 0
5906 }
5907
5908 test_56xb() {
5909         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
5910                 skip "Need MDS version at least 2.10.55"
5911
5912         local dir="$DIR/$tdir"
5913
5914         test_mkdir "$dir" || error "cannot create dir $dir"
5915
5916         echo "testing lfs migrate mode when all links fit within xattrs"
5917         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
5918
5919         echo "testing rsync mode when all links fit within xattrs"
5920         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
5921
5922         echo "testing lfs migrate mode when all links do not fit within xattrs"
5923         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
5924
5925         echo "testing rsync mode when all links do not fit within xattrs"
5926         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
5927
5928
5929         # clean up
5930         rm -rf $dir
5931 }
5932 run_test 56xb "lfs migration hard link support"
5933
5934 test_56xc() {
5935         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5936
5937         local dir="$DIR/$tdir"
5938
5939         test_mkdir "$dir" || error "cannot create dir $dir"
5940
5941         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
5942         echo -n "Setting initial stripe for 20MB test file..."
5943         $LFS setstripe -c 2 -i 0 "$dir/20mb" || error "cannot setstripe"
5944         echo "done"
5945         echo -n "Sizing 20MB test file..."
5946         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
5947         echo "done"
5948         echo -n "Verifying small file autostripe count is 1..."
5949         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" &> /dev/null ||
5950                 error "cannot migrate 20MB file"
5951         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
5952                 error "cannot get stripe for $dir/20mb"
5953         [ $stripe_count -eq 1 ] ||
5954                 error "unexpected stripe count $stripe_count for 20MB file"
5955         rm -f "$dir/20mb"
5956         echo "done"
5957
5958         # Test 2: File is small enough to fit within the available space on
5959         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
5960         # have at least an additional 1KB for each desired stripe for test 3
5961         echo -n "Setting stripe for 1GB test file..."
5962         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe"
5963         echo "done"
5964         echo -n "Sizing 1GB test file..."
5965         # File size is 1GB + 3KB
5966         truncate "$dir/1gb" 1073744896 &> /dev/null ||
5967                 error "cannot create 1GB test file"
5968         echo "done"
5969         echo -n "Migrating 1GB file..."
5970         $LFS_MIGRATE -y -A -C 1 "$dir/1gb" &> /dev/null ||
5971                 error "cannot migrate file"
5972         echo "done"
5973         echo -n "Verifying autostripe count is sqrt(n) + 1..."
5974         stripe_count=$($LFS getstripe -c "$dir/1gb") ||
5975                 error "cannot get stripe for $dir/1gb"
5976         [ $stripe_count -eq 2 ] ||
5977                 error "unexpected stripe count $stripe_count (expected 2)"
5978         echo "done"
5979
5980         # Test 3: File is too large to fit within the available space on
5981         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
5982         if [ $OSTCOUNT -ge 3 ]; then
5983                 # The required available space is calculated as
5984                 # file size (1GB + 3KB) / OST count (3).
5985                 local kb_per_ost=349526
5986
5987                 echo -n "Migrating 1GB file..."
5988                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" &>> \
5989                         /dev/null || error "cannot migrate file"
5990                 echo "done"
5991
5992                 stripe_count=$($LFS getstripe -c "$dir/1gb")
5993                 echo -n "Verifying autostripe count with limited space..."
5994                 [ "$stripe_count" -a $stripe_count -eq 3 ] ||
5995                         error "unexpected stripe count $stripe_count (wanted 3)"
5996                 echo "done"
5997         fi
5998
5999         # clean up
6000         rm -rf $dir
6001 }
6002 run_test 56xc "lfs migration autostripe"
6003
6004 test_56y() {
6005         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
6006                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
6007
6008         local res=""
6009         local dir=$DIR/$tdir
6010         local f1=$dir/file1
6011         local f2=$dir/file2
6012
6013         test_mkdir -p $dir || error "creating dir $dir"
6014         touch $f1 || error "creating std file $f1"
6015         $MULTIOP $f2 H2c || error "creating released file $f2"
6016
6017         # a directory can be raid0, so ask only for files
6018         res=$($LFS find $dir -L raid0 -type f | wc -l)
6019         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
6020
6021         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
6022         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
6023
6024         # only files can be released, so no need to force file search
6025         res=$($LFS find $dir -L released)
6026         [[ $res == $f2 ]] || error "search released: found $res != $f2"
6027
6028         res=$($LFS find $dir -type f \! -L released)
6029         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
6030 }
6031 run_test 56y "lfs find -L raid0|released"
6032
6033 test_56z() { # LU-4824
6034         # This checks to make sure 'lfs find' continues after errors
6035         # There are two classes of errors that should be caught:
6036         # - If multiple paths are provided, all should be searched even if one
6037         #   errors out
6038         # - If errors are encountered during the search, it should not terminate
6039         #   early
6040         local dir=$DIR/$tdir
6041         local i
6042
6043         test_mkdir $dir
6044         for i in d{0..9}; do
6045                 test_mkdir $dir/$i
6046         done
6047         touch $dir/d{0..9}/$tfile
6048         $LFS find $DIR/non_existent_dir $dir &&
6049                 error "$LFS find did not return an error"
6050         # Make a directory unsearchable. This should NOT be the last entry in
6051         # directory order.  Arbitrarily pick the 6th entry
6052         chmod 700 $($LFS find $dir -type d | sed '6!d')
6053
6054         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
6055
6056         # The user should be able to see 10 directories and 9 files
6057         [ $count == 19 ] || error "$LFS find did not continue after error"
6058 }
6059 run_test 56z "lfs find should continue after an error"
6060
6061 test_56aa() { # LU-5937
6062         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
6063
6064         local dir=$DIR/$tdir
6065
6066         mkdir $dir
6067         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
6068
6069         createmany -o $dir/striped_dir/${tfile}- 1024
6070         local dirs=$($LFS find --size +8k $dir/)
6071
6072         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
6073 }
6074 run_test 56aa "lfs find --size under striped dir"
6075
6076 test_56ab() { # LU-10705
6077         test_mkdir $DIR/$tdir
6078         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
6079         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
6080         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
6081         # Flush writes to ensure valid blocks.  Need to be more thorough for
6082         # ZFS, since blocks are not allocated/returned to client immediately.
6083         sync_all_data
6084         wait_zfs_commit ost1 2
6085         cancel_lru_locks osc
6086         ls -ls $DIR/$tdir
6087
6088         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
6089
6090         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
6091
6092         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
6093         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
6094
6095         rm -f $DIR/$tdir/$tfile.[123]
6096 }
6097 run_test 56ab "lfs find --blocks"
6098
6099 test_56ba() {
6100         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
6101                 skip "Need MDS version at least 2.10.50"
6102
6103         # Create composite files with one component
6104         local dir=$DIR/$tdir
6105
6106         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
6107         # Create composite files with three components
6108         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
6109         # Create non-composite files
6110         createmany -o $dir/${tfile}- 10
6111
6112         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
6113
6114         [[ $nfiles == 10 ]] ||
6115                 error "lfs find -E 1M found $nfiles != 10 files"
6116
6117         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
6118         [[ $nfiles == 25 ]] ||
6119                 error "lfs find ! -E 1M found $nfiles != 25 files"
6120
6121         # All files have a component that starts at 0
6122         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
6123         [[ $nfiles == 35 ]] ||
6124                 error "lfs find --component-start 0 - $nfiles != 35 files"
6125
6126         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
6127         [[ $nfiles == 15 ]] ||
6128                 error "lfs find --component-start 2M - $nfiles != 15 files"
6129
6130         # All files created here have a componenet that does not starts at 2M
6131         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
6132         [[ $nfiles == 35 ]] ||
6133                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
6134
6135         # Find files with a specified number of components
6136         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
6137         [[ $nfiles == 15 ]] ||
6138                 error "lfs find --component-count 3 - $nfiles != 15 files"
6139
6140         # Remember non-composite files have a component count of zero
6141         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
6142         [[ $nfiles == 10 ]] ||
6143                 error "lfs find --component-count 0 - $nfiles != 10 files"
6144
6145         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
6146         [[ $nfiles == 20 ]] ||
6147                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
6148
6149         # All files have a flag called "init"
6150         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
6151         [[ $nfiles == 35 ]] ||
6152                 error "lfs find --component-flags init - $nfiles != 35 files"
6153
6154         # Multi-component files will have a component not initialized
6155         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
6156         [[ $nfiles == 15 ]] ||
6157                 error "lfs find !--component-flags init - $nfiles != 15 files"
6158
6159         rm -rf $dir
6160
6161 }
6162 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
6163
6164 test_56ca() {
6165         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
6166                 skip "Need MDS version at least 2.10.57"
6167
6168         local td=$DIR/$tdir
6169         local tf=$td/$tfile
6170         local dir
6171         local nfiles
6172         local cmd
6173         local i
6174         local j
6175
6176         # create mirrored directories and mirrored files
6177         mkdir $td || error "mkdir $td failed"
6178         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
6179         createmany -o $tf- 10 || error "create $tf- failed"
6180
6181         for i in $(seq 2); do
6182                 dir=$td/dir$i
6183                 mkdir $dir || error "mkdir $dir failed"
6184                 $LFS mirror create -N$((3 + i)) $dir ||
6185                         error "create mirrored dir $dir failed"
6186                 createmany -o $dir/$tfile- 10 ||
6187                         error "create $dir/$tfile- failed"
6188         done
6189
6190         # change the states of some mirrored files
6191         echo foo > $tf-6
6192         for i in $(seq 2); do
6193                 dir=$td/dir$i
6194                 for j in $(seq 4 9); do
6195                         echo foo > $dir/$tfile-$j
6196                 done
6197         done
6198
6199         # find mirrored files with specific mirror count
6200         cmd="$LFS find --mirror-count 3 --type f $td"
6201         nfiles=$($cmd | wc -l)
6202         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
6203
6204         cmd="$LFS find ! --mirror-count 3 --type f $td"
6205         nfiles=$($cmd | wc -l)
6206         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
6207
6208         cmd="$LFS find --mirror-count +2 --type f $td"
6209         nfiles=$($cmd | wc -l)
6210         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6211
6212         cmd="$LFS find --mirror-count -6 --type f $td"
6213         nfiles=$($cmd | wc -l)
6214         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6215
6216         # find mirrored files with specific file state
6217         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
6218         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
6219
6220         cmd="$LFS find --mirror-state=ro --type f $td"
6221         nfiles=$($cmd | wc -l)
6222         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
6223
6224         cmd="$LFS find ! --mirror-state=ro --type f $td"
6225         nfiles=$($cmd | wc -l)
6226         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6227
6228         cmd="$LFS find --mirror-state=wp --type f $td"
6229         nfiles=$($cmd | wc -l)
6230         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6231
6232         cmd="$LFS find ! --mirror-state=sp --type f $td"
6233         nfiles=$($cmd | wc -l)
6234         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6235 }
6236 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
6237
6238 test_57a() {
6239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6240         # note test will not do anything if MDS is not local
6241         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6242                 skip_env "ldiskfs only test"
6243         fi
6244         remote_mds_nodsh && skip "remote MDS with nodsh"
6245
6246         local MNTDEV="osd*.*MDT*.mntdev"
6247         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
6248         [ -z "$DEV" ] && error "can't access $MNTDEV"
6249         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
6250                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
6251                         error "can't access $DEV"
6252                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
6253                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
6254                 rm $TMP/t57a.dump
6255         done
6256 }
6257 run_test 57a "verify MDS filesystem created with large inodes =="
6258
6259 test_57b() {
6260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6261         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6262                 skip_env "ldiskfs only test"
6263         fi
6264         remote_mds_nodsh && skip "remote MDS with nodsh"
6265
6266         local dir=$DIR/$tdir
6267         local filecount=100
6268         local file1=$dir/f1
6269         local fileN=$dir/f$filecount
6270
6271         rm -rf $dir || error "removing $dir"
6272         test_mkdir -c1 $dir
6273         local mdtidx=$($LFS getstripe -m $dir)
6274         local mdtname=MDT$(printf %04x $mdtidx)
6275         local facet=mds$((mdtidx + 1))
6276
6277         echo "mcreating $filecount files"
6278         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
6279
6280         # verify that files do not have EAs yet
6281         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
6282                 error "$file1 has an EA"
6283         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
6284                 error "$fileN has an EA"
6285
6286         sync
6287         sleep 1
6288         df $dir  #make sure we get new statfs data
6289         local mdsfree=$(do_facet $facet \
6290                         lctl get_param -n osd*.*$mdtname.kbytesfree)
6291         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6292         local file
6293
6294         echo "opening files to create objects/EAs"
6295         for file in $(seq -f $dir/f%g 1 $filecount); do
6296                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
6297                         error "opening $file"
6298         done
6299
6300         # verify that files have EAs now
6301         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
6302         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
6303
6304         sleep 1  #make sure we get new statfs data
6305         df $dir
6306         local mdsfree2=$(do_facet $facet \
6307                          lctl get_param -n osd*.*$mdtname.kbytesfree)
6308         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6309
6310         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
6311                 if [ "$mdsfree" != "$mdsfree2" ]; then
6312                         error "MDC before $mdcfree != after $mdcfree2"
6313                 else
6314                         echo "MDC before $mdcfree != after $mdcfree2"
6315                         echo "unable to confirm if MDS has large inodes"
6316                 fi
6317         fi
6318         rm -rf $dir
6319 }
6320 run_test 57b "default LOV EAs are stored inside large inodes ==="
6321
6322 test_58() {
6323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6324         [ -z "$(which wiretest 2>/dev/null)" ] &&
6325                         skip_env "could not find wiretest"
6326
6327         wiretest
6328 }
6329 run_test 58 "verify cross-platform wire constants =============="
6330
6331 test_59() {
6332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6333
6334         echo "touch 130 files"
6335         createmany -o $DIR/f59- 130
6336         echo "rm 130 files"
6337         unlinkmany $DIR/f59- 130
6338         sync
6339         # wait for commitment of removal
6340         wait_delete_completed
6341 }
6342 run_test 59 "verify cancellation of llog records async ========="
6343
6344 TEST60_HEAD="test_60 run $RANDOM"
6345 test_60a() {
6346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6347         remote_mgs_nodsh && skip "remote MGS with nodsh"
6348         do_facet mgs "! which run-llog.sh &> /dev/null" &&
6349                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
6350                         skip_env "missing subtest run-llog.sh"
6351
6352         log "$TEST60_HEAD - from kernel mode"
6353         do_facet mgs "$LCTL dk > /dev/null"
6354         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
6355         do_facet mgs $LCTL dk > $TMP/$tfile
6356
6357         # LU-6388: test llog_reader
6358         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
6359         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
6360         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
6361                         skip_env "missing llog_reader"
6362         local fstype=$(facet_fstype mgs)
6363         [ $fstype != ldiskfs -a $fstype != zfs ] &&
6364                 skip_env "Only for ldiskfs or zfs type mgs"
6365
6366         local mntpt=$(facet_mntpt mgs)
6367         local mgsdev=$(mgsdevname 1)
6368         local fid_list
6369         local fid
6370         local rec_list
6371         local rec
6372         local rec_type
6373         local obj_file
6374         local path
6375         local seq
6376         local oid
6377         local pass=true
6378
6379         #get fid and record list
6380         fid_list=($(awk '/9_sub.*record/ { print $NF }' /$TMP/$tfile |
6381                 tail -n 4))
6382         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' /$TMP/$tfile |
6383                 tail -n 4))
6384         #remount mgs as ldiskfs or zfs type
6385         stop mgs || error "stop mgs failed"
6386         mount_fstype mgs || error "remount mgs failed"
6387         for ((i = 0; i < ${#fid_list[@]}; i++)); do
6388                 fid=${fid_list[i]}
6389                 rec=${rec_list[i]}
6390                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
6391                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
6392                 oid=$((16#$oid))
6393
6394                 case $fstype in
6395                         ldiskfs )
6396                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
6397                         zfs )
6398                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
6399                 esac
6400                 echo "obj_file is $obj_file"
6401                 do_facet mgs $llog_reader $obj_file
6402
6403                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
6404                         awk '{ print $3 }' | sed -e "s/^type=//g")
6405                 if [ $rec_type != $rec ]; then
6406                         echo "FAILED test_60a wrong record type $rec_type," \
6407                               "should be $rec"
6408                         pass=false
6409                         break
6410                 fi
6411
6412                 #check obj path if record type is LLOG_LOGID_MAGIC
6413                 if [ "$rec" == "1064553b" ]; then
6414                         path=$(do_facet mgs $llog_reader $obj_file |
6415                                 grep "path=" | awk '{ print $NF }' |
6416                                 sed -e "s/^path=//g")
6417                         if [ $obj_file != $mntpt/$path ]; then
6418                                 echo "FAILED test_60a wrong obj path" \
6419                                       "$montpt/$path, should be $obj_file"
6420                                 pass=false
6421                                 break
6422                         fi
6423                 fi
6424         done
6425         rm -f $TMP/$tfile
6426         #restart mgs before "error", otherwise it will block the next test
6427         stop mgs || error "stop mgs failed"
6428         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
6429         $pass || error "test failed, see FAILED test_60a messages for specifics"
6430 }
6431 run_test 60a "llog_test run from kernel module and test llog_reader"
6432
6433 test_60b() { # bug 6411
6434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6435
6436         dmesg > $DIR/$tfile
6437         LLOG_COUNT=$(do_facet mgs dmesg |
6438                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
6439                           /llog_[a-z]*.c:[0-9]/ {
6440                                 if (marker)
6441                                         from_marker++
6442                                 from_begin++
6443                           }
6444                           END {
6445                                 if (marker)
6446                                         print from_marker
6447                                 else
6448                                         print from_begin
6449                           }")
6450
6451         [[ $LLOG_COUNT -gt 120 ]] &&
6452                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
6453 }
6454 run_test 60b "limit repeated messages from CERROR/CWARN"
6455
6456 test_60c() {
6457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6458
6459         echo "create 5000 files"
6460         createmany -o $DIR/f60c- 5000
6461 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
6462         lctl set_param fail_loc=0x80000137
6463         unlinkmany $DIR/f60c- 5000
6464         lctl set_param fail_loc=0
6465 }
6466 run_test 60c "unlink file when mds full"
6467
6468 test_60d() {
6469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6470
6471         SAVEPRINTK=$(lctl get_param -n printk)
6472         # verify "lctl mark" is even working"
6473         MESSAGE="test message ID $RANDOM $$"
6474         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6475         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
6476
6477         lctl set_param printk=0 || error "set lnet.printk failed"
6478         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
6479         MESSAGE="new test message ID $RANDOM $$"
6480         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
6481         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6482         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
6483
6484         lctl set_param -n printk="$SAVEPRINTK"
6485 }
6486 run_test 60d "test printk console message masking"
6487
6488 test_60e() {
6489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6490         remote_mds_nodsh && skip "remote MDS with nodsh"
6491
6492         touch $DIR/$tfile
6493 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
6494         do_facet mds1 lctl set_param fail_loc=0x15b
6495         rm $DIR/$tfile
6496 }
6497 run_test 60e "no space while new llog is being created"
6498
6499 test_60g() {
6500         local pid
6501
6502         test_mkdir -c $MDSCOUNT $DIR/$tdir
6503         $LFS setdirstripe -D -i -1 -c $MDSCOUNT $DIR/$tdir
6504
6505         (
6506                 local index=0
6507                 while true; do
6508                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
6509                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
6510                         index=$((index + 1))
6511                 done
6512         ) &
6513
6514         pid=$!
6515
6516         for i in $(seq 100); do 
6517                 # define OBD_FAIL_OSD_TXN_START    0x19a
6518                 do_facet mds1 lctl set_param fail_loc=0x8000019a
6519                 usleep 100
6520         done
6521
6522         kill -9 $pid
6523
6524         mkdir $DIR/$tdir/new || error "mkdir failed"
6525         rmdir $DIR/$tdir/new || error "rmdir failed"
6526 }
6527 run_test 60g "transaction abort won't cause MDT hung"
6528
6529 test_61a() {
6530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6531
6532         f="$DIR/f61"
6533         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
6534         cancel_lru_locks osc
6535         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
6536         sync
6537 }
6538 run_test 61a "mmap() writes don't make sync hang ================"
6539
6540 test_61b() {
6541         mmap_mknod_test $tfile || error "mmap_mknod_test failed"
6542 }
6543 run_test 61b "mmap() of unstriped file is successful"
6544
6545 # bug 2330 - insufficient obd_match error checking causes LBUG
6546 test_62() {
6547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6548
6549         f="$DIR/f62"
6550         echo foo > $f
6551         cancel_lru_locks osc
6552         lctl set_param fail_loc=0x405
6553         cat $f && error "cat succeeded, expect -EIO"
6554         lctl set_param fail_loc=0
6555 }
6556 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
6557 # match every page all of the time.
6558 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
6559
6560 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
6561 # Though this test is irrelevant anymore, it helped to reveal some
6562 # other grant bugs (LU-4482), let's keep it.
6563 test_63a() {   # was test_63
6564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6565
6566         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
6567
6568         for i in `seq 10` ; do
6569                 dd if=/dev/zero of=$DIR/f63 bs=8k &
6570                 sleep 5
6571                 kill $!
6572                 sleep 1
6573         done
6574
6575         rm -f $DIR/f63 || true
6576 }
6577 run_test 63a "Verify oig_wait interruption does not crash ======="
6578
6579 # bug 2248 - async write errors didn't return to application on sync
6580 # bug 3677 - async write errors left page locked
6581 test_63b() {
6582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6583
6584         debugsave
6585         lctl set_param debug=-1
6586
6587         # ensure we have a grant to do async writes
6588         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
6589         rm $DIR/$tfile
6590
6591         sync    # sync lest earlier test intercept the fail_loc
6592
6593         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
6594         lctl set_param fail_loc=0x80000406
6595         $MULTIOP $DIR/$tfile Owy && \
6596                 error "sync didn't return ENOMEM"
6597         sync; sleep 2; sync     # do a real sync this time to flush page
6598         lctl get_param -n llite.*.dump_page_cache | grep locked && \
6599                 error "locked page left in cache after async error" || true
6600         debugrestore
6601 }
6602 run_test 63b "async write errors should be returned to fsync ==="
6603
6604 test_64a () {
6605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6606
6607         df $DIR
6608         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
6609 }
6610 run_test 64a "verify filter grant calculations (in kernel) ====="
6611
6612 test_64b () {
6613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6614
6615         sh oos.sh $MOUNT || error "oos.sh failed: $?"
6616 }
6617 run_test 64b "check out-of-space detection on client"
6618
6619 test_64c() {
6620         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
6621 }
6622 run_test 64c "verify grant shrink"
6623
6624 # this does exactly what osc_request.c:osc_announce_cached() does in
6625 # order to calculate max amount of grants to ask from server
6626 want_grant() {
6627         local tgt=$1
6628
6629         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
6630         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
6631
6632         ((rpc_in_flight ++));
6633         nrpages=$((nrpages * rpc_in_flight))
6634
6635         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
6636
6637         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
6638
6639         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
6640         local undirty=$((nrpages * PAGE_SIZE))
6641
6642         local max_extent_pages
6643         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
6644             grep grant_max_extent_size | awk '{print $2}')
6645         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
6646         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
6647         local grant_extent_tax
6648         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
6649             grep grant_extent_tax | awk '{print $2}')
6650
6651         undirty=$((undirty + nrextents * grant_extent_tax))
6652
6653         echo $undirty
6654 }
6655
6656 # this is size of unit for grant allocation. It should be equal to
6657 # what tgt_grant.c:tgt_grant_chunk() calculates
6658 grant_chunk() {
6659         local tgt=$1
6660         local max_brw_size
6661         local grant_extent_tax
6662
6663         max_brw_size=$($LCTL get_param osc.${tgt}.import |
6664             grep max_brw_size | awk '{print $2}')
6665
6666         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
6667             grep grant_extent_tax | awk '{print $2}')
6668
6669         echo $(((max_brw_size + grant_extent_tax) * 2))
6670 }
6671
6672 test_64d() {
6673         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
6674                 skip "OST < 2.10.55 doesn't limit grants enough"
6675
6676         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
6677         local file=$DIR/$tfile
6678
6679         [[ $($LCTL get_param osc.${tgt}.import |
6680              grep "connect_flags:.*grant_param") ]] ||
6681                 skip "no grant_param connect flag"
6682
6683         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
6684
6685         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
6686
6687         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
6688         stack_trap "rm -f $file" EXIT
6689
6690         $LFS setstripe $file -i 0 -c 1
6691         dd if=/dev/zero of=$file bs=1M count=1000 &
6692         ddpid=$!
6693
6694         while true
6695         do
6696                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
6697                 if [[ $cur_grant -gt $max_cur_granted ]]
6698                 then
6699                         kill $ddpid
6700                         error "cur_grant $cur_grant > $max_cur_granted"
6701                 fi
6702                 kill -0 $ddpid
6703                 [[ $? -ne 0 ]] && break;
6704                 sleep 2
6705         done
6706
6707         rm -f $DIR/$tfile
6708         wait_delete_completed
6709         $LCTL set_param debug="$olddebug" 2> /dev/null || true
6710 }
6711 run_test 64d "check grant limit exceed"
6712
6713 # bug 1414 - set/get directories' stripe info
6714 test_65a() {
6715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6716
6717         test_mkdir $DIR/$tdir
6718         touch $DIR/$tdir/f1
6719         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
6720 }
6721 run_test 65a "directory with no stripe info"
6722
6723 test_65b() {
6724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6725
6726         test_mkdir $DIR/$tdir
6727         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6728
6729         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6730                                                 error "setstripe"
6731         touch $DIR/$tdir/f2
6732         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
6733 }
6734 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
6735
6736 test_65c() {
6737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6738         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
6739
6740         test_mkdir $DIR/$tdir
6741         local stripesize=$($LFS getstripe -S $DIR/$tdir)
6742
6743         $LFS setstripe -S $((stripesize * 4)) -i 1 \
6744                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
6745         touch $DIR/$tdir/f3
6746         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
6747 }
6748 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
6749
6750 test_65d() {
6751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6752
6753         test_mkdir $DIR/$tdir
6754         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
6755         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6756
6757         if [[ $STRIPECOUNT -le 0 ]]; then
6758                 sc=1
6759         elif [[ $STRIPECOUNT -gt 2000 ]]; then
6760 #LOV_MAX_STRIPE_COUNT is 2000
6761                 [[ $OSTCOUNT -gt 2000 ]] && sc=2000 || sc=$(($OSTCOUNT - 1))
6762         else
6763                 sc=$(($STRIPECOUNT - 1))
6764         fi
6765         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
6766         touch $DIR/$tdir/f4 $DIR/$tdir/f5
6767         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
6768                 error "lverify failed"
6769 }
6770 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
6771
6772 test_65e() {
6773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6774
6775         test_mkdir $DIR/$tdir
6776
6777         $LFS setstripe $DIR/$tdir || error "setstripe"
6778         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
6779                                         error "no stripe info failed"
6780         touch $DIR/$tdir/f6
6781         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
6782 }
6783 run_test 65e "directory setstripe defaults"
6784
6785 test_65f() {
6786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6787
6788         test_mkdir $DIR/${tdir}f
6789         $RUNAS $LFS setstripe $DIR/${tdir}f &&
6790                 error "setstripe succeeded" || true
6791 }
6792 run_test 65f "dir setstripe permission (should return error) ==="
6793
6794 test_65g() {
6795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6796
6797         test_mkdir $DIR/$tdir
6798         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6799
6800         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6801                 error "setstripe -S failed"
6802         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
6803         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
6804                 error "delete default stripe failed"
6805 }
6806 run_test 65g "directory setstripe -d"
6807
6808 test_65h() {
6809         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6810
6811         test_mkdir $DIR/$tdir
6812         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6813
6814         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6815                 error "setstripe -S failed"
6816         test_mkdir $DIR/$tdir/dd1
6817         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
6818                 error "stripe info inherit failed"
6819 }
6820 run_test 65h "directory stripe info inherit ===================="
6821
6822 test_65i() {
6823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6824
6825         save_layout_restore_at_exit $MOUNT
6826
6827         # bug6367: set non-default striping on root directory
6828         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
6829
6830         # bug12836: getstripe on -1 default directory striping
6831         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
6832
6833         # bug12836: getstripe -v on -1 default directory striping
6834         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
6835
6836         # bug12836: new find on -1 default directory striping
6837         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
6838 }
6839 run_test 65i "various tests to set root directory striping"
6840
6841 test_65j() { # bug6367
6842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6843
6844         sync; sleep 1
6845
6846         # if we aren't already remounting for each test, do so for this test
6847         if [ "$CLEANUP" = ":" -a "$I_MOUNTED" = "yes" ]; then
6848                 cleanup || error "failed to unmount"
6849                 setup
6850         fi
6851
6852         save_layout_restore_at_exit $MOUNT
6853
6854         $LFS setstripe -d $MOUNT || error "setstripe failed"
6855 }
6856 run_test 65j "set default striping on root directory (bug 6367)="
6857
6858 cleanup_65k() {
6859         rm -rf $DIR/$tdir
6860         wait_delete_completed
6861         do_facet $SINGLEMDS "lctl set_param -n \
6862                 osp.$ost*MDT0000.max_create_count=$max_count"
6863         do_facet $SINGLEMDS "lctl set_param -n \
6864                 osp.$ost*MDT0000.create_count=$count"
6865         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
6866         echo $INACTIVE_OSC "is Activate"
6867
6868         wait_osc_import_state mds ost$ostnum FULL
6869 }
6870
6871 test_65k() { # bug11679
6872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6873         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6874         remote_mds_nodsh && skip "remote MDS with nodsh"
6875
6876         local disable_precreate=true
6877         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
6878                 disable_precreate=false
6879
6880         echo "Check OST status: "
6881         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
6882                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
6883
6884         for OSC in $MDS_OSCS; do
6885                 echo $OSC "is active"
6886                 do_facet $SINGLEMDS lctl --device %$OSC activate
6887         done
6888
6889         for INACTIVE_OSC in $MDS_OSCS; do
6890                 local ost=$(osc_to_ost $INACTIVE_OSC)
6891                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
6892                                lov.*md*.target_obd |
6893                                awk -F: /$ost/'{ print $1 }' | head -n 1)
6894
6895                 mkdir -p $DIR/$tdir
6896                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
6897                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
6898
6899                 echo "Deactivate: " $INACTIVE_OSC
6900                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
6901
6902                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
6903                               osp.$ost*MDT0000.create_count")
6904                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
6905                                   osp.$ost*MDT0000.max_create_count")
6906                 $disable_precreate &&
6907                         do_facet $SINGLEMDS "lctl set_param -n \
6908                                 osp.$ost*MDT0000.max_create_count=0"
6909
6910                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
6911                         [ -f $DIR/$tdir/$idx ] && continue
6912                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
6913                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
6914                                 { cleanup_65k;
6915                                   error "setstripe $idx should succeed"; }
6916                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
6917                 done
6918                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
6919                 rmdir $DIR/$tdir
6920
6921                 do_facet $SINGLEMDS "lctl set_param -n \
6922                         osp.$ost*MDT0000.max_create_count=$max_count"
6923                 do_facet $SINGLEMDS "lctl set_param -n \
6924                         osp.$ost*MDT0000.create_count=$count"
6925                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
6926                 echo $INACTIVE_OSC "is Activate"
6927
6928                 wait_osc_import_state mds ost$ostnum FULL
6929         done
6930 }
6931 run_test 65k "validate manual striping works properly with deactivated OSCs"
6932
6933 test_65l() { # bug 12836
6934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6935
6936         test_mkdir -p $DIR/$tdir/test_dir
6937         $LFS setstripe -c -1 $DIR/$tdir/test_dir
6938         $LFS find -mtime -1 $DIR/$tdir >/dev/null
6939 }
6940 run_test 65l "lfs find on -1 stripe dir ========================"
6941
6942 test_65m() {
6943         local layout=$(save_layout $MOUNT)
6944         $RUNAS $LFS setstripe -c 2 $MOUNT && {
6945                 restore_layout $MOUNT $layout
6946                 error "setstripe should fail by non-root users"
6947         }
6948         true
6949 }
6950 run_test 65m "normal user can't set filesystem default stripe"
6951
6952 test_65n() {
6953         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
6954         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.12.50) ]] ||
6955                 skip "Need MDS version at least 2.12.50"
6956         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
6957
6958         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
6959         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
6960         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
6961
6962         local root_layout=$(save_layout $MOUNT)
6963         stack_trap "restore_layout $MOUNT $root_layout" EXIT
6964
6965         # new subdirectory under root directory should not inherit
6966         # the default layout from root
6967         local dir1=$MOUNT/$tdir-1
6968         mkdir $dir1 || error "mkdir $dir1 failed"
6969         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
6970                 error "$dir1 shouldn't have LOV EA"
6971
6972         # delete the default layout on root directory
6973         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
6974
6975         local dir2=$MOUNT/$tdir-2
6976         mkdir $dir2 || error "mkdir $dir2 failed"
6977         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
6978                 error "$dir2 shouldn't have LOV EA"
6979
6980         # set a new striping pattern on root directory
6981         local def_stripe_size=$($LFS getstripe -S $MOUNT)
6982         local new_def_stripe_size=$((def_stripe_size * 2))
6983         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
6984                 error "set stripe size on $MOUNT failed"
6985
6986         # new file created in $dir2 should inherit the new stripe size from
6987         # the filesystem default
6988         local file2=$dir2/$tfile-2
6989         touch $file2 || error "touch $file2 failed"
6990
6991         local file2_stripe_size=$($LFS getstripe -S $file2)
6992         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
6993                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
6994
6995         local dir3=$MOUNT/$tdir-3
6996         mkdir $dir3 || error "mkdir $dir3 failed"
6997         ! getfattr -n trusted.lov $dir3 &> /dev/null ||
6998                 error "$dir3 shouldn't have LOV EA"
6999
7000         # set OST pool on root directory
7001         local pool=$TESTNAME
7002         pool_add $pool || error "add $pool failed"
7003         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
7004                 error "add targets to $pool failed"
7005
7006         $LFS setstripe -p $pool $MOUNT ||
7007                 error "set OST pool on $MOUNT failed"
7008
7009         # new file created in $dir3 should inherit the pool from
7010         # the filesystem default
7011         local file3=$dir3/$tfile-3
7012         touch $file3 || error "touch $file3 failed"
7013
7014         local file3_pool=$($LFS getstripe -p $file3)
7015         [[ "$file3_pool" = "$pool" ]] ||
7016                 error "$file3 didn't inherit OST pool $pool"
7017
7018         local dir4=$MOUNT/$tdir-4
7019         mkdir $dir4 || error "mkdir $dir4 failed"
7020         ! getfattr -n trusted.lov $dir4 &> /dev/null ||
7021                 error "$dir4 shouldn't have LOV EA"
7022
7023         # new file created in $dir4 should inherit the pool from
7024         # the filesystem default
7025         local file4=$dir4/$tfile-4
7026         touch $file4 || error "touch $file4 failed"
7027
7028         local file4_pool=$($LFS getstripe -p $file4)
7029         [[ "$file4_pool" = "$pool" ]] ||
7030                 error "$file4 didn't inherit OST pool $pool"
7031
7032         # new subdirectory under non-root directory should inherit
7033         # the default layout from its parent directory
7034         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
7035                 error "set directory layout on $dir4 failed"
7036
7037         local dir5=$dir4/$tdir-5
7038         mkdir $dir5 || error "mkdir $dir5 failed"
7039
7040         local dir4_layout=$(get_layout_param $dir4)
7041         local dir5_layout=$(get_layout_param $dir5)
7042         [[ "$dir4_layout" = "$dir5_layout" ]] ||
7043                 error "$dir5 should inherit the default layout from $dir4"
7044 }
7045 run_test 65n "don't inherit default layout from root for new subdirectories"
7046
7047 # bug 2543 - update blocks count on client
7048 test_66() {
7049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7050
7051         COUNT=${COUNT:-8}
7052         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
7053         sync; sync_all_data; sync; sync_all_data
7054         cancel_lru_locks osc
7055         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
7056         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
7057 }
7058 run_test 66 "update inode blocks count on client ==============="
7059
7060 meminfo() {
7061         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
7062 }
7063
7064 swap_used() {
7065         swapon -s | awk '($1 == "'$1'") { print $4 }'
7066 }
7067
7068 # bug5265, obdfilter oa2dentry return -ENOENT
7069 # #define OBD_FAIL_SRV_ENOENT 0x217
7070 test_69() {
7071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7072         remote_ost_nodsh && skip "remote OST with nodsh"
7073
7074         f="$DIR/$tfile"
7075         $LFS setstripe -c 1 -i 0 $f
7076
7077         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
7078
7079         do_facet ost1 lctl set_param fail_loc=0x217
7080         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
7081         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
7082
7083         do_facet ost1 lctl set_param fail_loc=0
7084         $DIRECTIO write $f 0 2 || error "write error"
7085
7086         cancel_lru_locks osc
7087         $DIRECTIO read $f 0 1 || error "read error"
7088
7089         do_facet ost1 lctl set_param fail_loc=0x217
7090         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
7091
7092         do_facet ost1 lctl set_param fail_loc=0
7093         rm -f $f
7094 }
7095 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
7096
7097 test_71() {
7098         test_mkdir $DIR/$tdir
7099         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
7100         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
7101 }
7102 run_test 71 "Running dbench on lustre (don't segment fault) ===="
7103
7104 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
7105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7106         [ "$RUNAS_ID" = "$UID" ] &&
7107                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7108         # Check that testing environment is properly set up. Skip if not
7109         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
7110                 skip_env "User $RUNAS_ID does not exist - skipping"
7111
7112         touch $DIR/$tfile
7113         chmod 777 $DIR/$tfile
7114         chmod ug+s $DIR/$tfile
7115         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
7116                 error "$RUNAS dd $DIR/$tfile failed"
7117         # See if we are still setuid/sgid
7118         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7119                 error "S/gid is not dropped on write"
7120         # Now test that MDS is updated too
7121         cancel_lru_locks mdc
7122         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7123                 error "S/gid is not dropped on MDS"
7124         rm -f $DIR/$tfile
7125 }
7126 run_test 72a "Test that remove suid works properly (bug5695) ===="
7127
7128 test_72b() { # bug 24226 -- keep mode setting when size is not changing
7129         local perm
7130
7131         [ "$RUNAS_ID" = "$UID" ] &&
7132                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7133         [ "$RUNAS_ID" -eq 0 ] &&
7134                 skip_env "RUNAS_ID = 0 -- skipping"
7135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7136         # Check that testing environment is properly set up. Skip if not
7137         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
7138                 skip_env "User $RUNAS_ID does not exist - skipping"
7139
7140         touch $DIR/${tfile}-f{g,u}
7141         test_mkdir $DIR/${tfile}-dg
7142         test_mkdir $DIR/${tfile}-du
7143         chmod 770 $DIR/${tfile}-{f,d}{g,u}
7144         chmod g+s $DIR/${tfile}-{f,d}g
7145         chmod u+s $DIR/${tfile}-{f,d}u
7146         for perm in 777 2777 4777; do
7147                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
7148                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
7149                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
7150                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
7151         done
7152         true
7153 }
7154 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
7155
7156 # bug 3462 - multiple simultaneous MDC requests
7157 test_73() {
7158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7159
7160         test_mkdir $DIR/d73-1
7161         test_mkdir $DIR/d73-2
7162         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
7163         pid1=$!
7164
7165         lctl set_param fail_loc=0x80000129
7166         $MULTIOP $DIR/d73-1/f73-2 Oc &
7167         sleep 1
7168         lctl set_param fail_loc=0
7169
7170         $MULTIOP $DIR/d73-2/f73-3 Oc &
7171         pid3=$!
7172
7173         kill -USR1 $pid1
7174         wait $pid1 || return 1
7175
7176         sleep 25
7177
7178         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
7179         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
7180         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
7181
7182         rm -rf $DIR/d73-*
7183 }
7184 run_test 73 "multiple MDC requests (should not deadlock)"
7185
7186 test_74a() { # bug 6149, 6184
7187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7188
7189         touch $DIR/f74a
7190         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7191         #
7192         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7193         # will spin in a tight reconnection loop
7194         $LCTL set_param fail_loc=0x8000030e
7195         # get any lock that won't be difficult - lookup works.
7196         ls $DIR/f74a
7197         $LCTL set_param fail_loc=0
7198         rm -f $DIR/f74a
7199         true
7200 }
7201 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
7202
7203 test_74b() { # bug 13310
7204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7205
7206         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7207         #
7208         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7209         # will spin in a tight reconnection loop
7210         $LCTL set_param fail_loc=0x8000030e
7211         # get a "difficult" lock
7212         touch $DIR/f74b
7213         $LCTL set_param fail_loc=0
7214         rm -f $DIR/f74b
7215         true
7216 }
7217 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
7218
7219 test_74c() {
7220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7221
7222         #define OBD_FAIL_LDLM_NEW_LOCK
7223         $LCTL set_param fail_loc=0x319
7224         touch $DIR/$tfile && error "touch successful"
7225         $LCTL set_param fail_loc=0
7226         true
7227 }
7228 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
7229
7230 num_inodes() {
7231         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
7232 }
7233
7234 test_76() { # Now for bug 20433, added originally in bug 1443
7235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7236
7237         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
7238
7239         cancel_lru_locks osc
7240         BEFORE_INODES=$(num_inodes)
7241         echo "before inodes: $BEFORE_INODES"
7242         local COUNT=1000
7243         [ "$SLOW" = "no" ] && COUNT=100
7244         for i in $(seq $COUNT); do
7245                 touch $DIR/$tfile
7246                 rm -f $DIR/$tfile
7247         done
7248         cancel_lru_locks osc
7249         AFTER_INODES=$(num_inodes)
7250         echo "after inodes: $AFTER_INODES"
7251         local wait=0
7252         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
7253                 sleep 2
7254                 AFTER_INODES=$(num_inodes)
7255                 wait=$((wait+2))
7256                 echo "wait $wait seconds inodes: $AFTER_INODES"
7257                 if [ $wait -gt 30 ]; then
7258                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
7259                 fi
7260         done
7261 }
7262 run_test 76 "confirm clients recycle inodes properly ===="
7263
7264
7265 export ORIG_CSUM=""
7266 set_checksums()
7267 {
7268         # Note: in sptlrpc modes which enable its own bulk checksum, the
7269         # original crc32_le bulk checksum will be automatically disabled,
7270         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
7271         # will be checked by sptlrpc code against sptlrpc bulk checksum.
7272         # In this case set_checksums() will not be no-op, because sptlrpc
7273         # bulk checksum will be enabled all through the test.
7274
7275         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
7276         lctl set_param -n osc.*.checksums $1
7277         return 0
7278 }
7279
7280 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7281                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
7282 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7283                              tr -d [] | head -n1)}
7284 set_checksum_type()
7285 {
7286         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
7287         log "set checksum type to $1"
7288         return 0
7289 }
7290 F77_TMP=$TMP/f77-temp
7291 F77SZ=8
7292 setup_f77() {
7293         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
7294                 error "error writing to $F77_TMP"
7295 }
7296
7297 test_77a() { # bug 10889
7298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7299         $GSS && skip_env "could not run with gss"
7300
7301         [ ! -f $F77_TMP ] && setup_f77
7302         set_checksums 1
7303         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
7304         set_checksums 0
7305         rm -f $DIR/$tfile
7306 }
7307 run_test 77a "normal checksum read/write operation"
7308
7309 test_77b() { # bug 10889
7310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7311         $GSS && skip_env "could not run with gss"
7312
7313         [ ! -f $F77_TMP ] && setup_f77
7314         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7315         $LCTL set_param fail_loc=0x80000409
7316         set_checksums 1
7317
7318         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7319                 error "dd error: $?"
7320         $LCTL set_param fail_loc=0
7321
7322         for algo in $CKSUM_TYPES; do
7323                 cancel_lru_locks osc
7324                 set_checksum_type $algo
7325                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7326                 $LCTL set_param fail_loc=0x80000408
7327                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
7328                 $LCTL set_param fail_loc=0
7329         done
7330         set_checksums 0
7331         set_checksum_type $ORIG_CSUM_TYPE
7332         rm -f $DIR/$tfile
7333 }
7334 run_test 77b "checksum error on client write, read"
7335
7336 cleanup_77c() {
7337         trap 0
7338         set_checksums 0
7339         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
7340         $check_ost &&
7341                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
7342         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
7343         $check_ost && [ -n "$ost_file_prefix" ] &&
7344                 do_facet ost1 rm -f ${ost_file_prefix}\*
7345 }
7346
7347 test_77c() {
7348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7349         $GSS && skip_env "could not run with gss"
7350         remote_ost_nodsh && skip "remote OST with nodsh"
7351
7352         local bad1
7353         local osc_file_prefix
7354         local osc_file
7355         local check_ost=false
7356         local ost_file_prefix
7357         local ost_file
7358         local orig_cksum
7359         local dump_cksum
7360         local fid
7361
7362         # ensure corruption will occur on first OSS/OST
7363         $LFS setstripe -i 0 $DIR/$tfile
7364
7365         [ ! -f $F77_TMP ] && setup_f77
7366         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7367                 error "dd write error: $?"
7368         fid=$($LFS path2fid $DIR/$tfile)
7369
7370         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
7371         then
7372                 check_ost=true
7373                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
7374                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
7375         else
7376                 echo "OSS do not support bulk pages dump upon error"
7377         fi
7378
7379         osc_file_prefix=$($LCTL get_param -n debug_path)
7380         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
7381
7382         trap cleanup_77c EXIT
7383
7384         set_checksums 1
7385         # enable bulk pages dump upon error on Client
7386         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
7387         # enable bulk pages dump upon error on OSS
7388         $check_ost &&
7389                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
7390
7391         # flush Client cache to allow next read to reach OSS
7392         cancel_lru_locks osc
7393
7394         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
7395         $LCTL set_param fail_loc=0x80000408
7396         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
7397         $LCTL set_param fail_loc=0
7398
7399         rm -f $DIR/$tfile
7400
7401         # check cksum dump on Client
7402         osc_file=$(ls ${osc_file_prefix}*)
7403         [ -n "$osc_file" ] || error "no checksum dump file on Client"
7404         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
7405         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
7406         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
7407         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
7408                      cksum)
7409         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
7410         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7411                 error "dump content does not match on Client"
7412
7413         $check_ost || skip "No need to check cksum dump on OSS"
7414
7415         # check cksum dump on OSS
7416         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
7417         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
7418         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
7419         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
7420         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7421                 error "dump content does not match on OSS"
7422
7423         cleanup_77c
7424 }
7425 run_test 77c "checksum error on client read with debug"
7426
7427 test_77d() { # bug 10889
7428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7429         $GSS && skip_env "could not run with gss"
7430
7431         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7432         $LCTL set_param fail_loc=0x80000409
7433         set_checksums 1
7434         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7435                 error "direct write: rc=$?"
7436         $LCTL set_param fail_loc=0
7437         set_checksums 0
7438
7439         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7440         $LCTL set_param fail_loc=0x80000408
7441         set_checksums 1
7442         cancel_lru_locks osc
7443         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7444                 error "direct read: rc=$?"
7445         $LCTL set_param fail_loc=0
7446         set_checksums 0
7447 }
7448 run_test 77d "checksum error on OST direct write, read"
7449
7450 test_77f() { # bug 10889
7451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7452         $GSS && skip_env "could not run with gss"
7453
7454         set_checksums 1
7455         for algo in $CKSUM_TYPES; do
7456                 cancel_lru_locks osc
7457                 set_checksum_type $algo
7458                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7459                 $LCTL set_param fail_loc=0x409
7460                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
7461                         error "direct write succeeded"
7462                 $LCTL set_param fail_loc=0
7463         done
7464         set_checksum_type $ORIG_CSUM_TYPE
7465         set_checksums 0
7466 }
7467 run_test 77f "repeat checksum error on write (expect error)"
7468
7469 test_77g() { # bug 10889
7470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7471         $GSS && skip_env "could not run with gss"
7472         remote_ost_nodsh && skip "remote OST with nodsh"
7473
7474         [ ! -f $F77_TMP ] && setup_f77
7475
7476         local file=$DIR/$tfile
7477         stack_trap "rm -f $file" EXIT
7478
7479         $LFS setstripe -c 1 -i 0 $file
7480         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
7481         do_facet ost1 lctl set_param fail_loc=0x8000021a
7482         set_checksums 1
7483         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
7484                 error "write error: rc=$?"
7485         do_facet ost1 lctl set_param fail_loc=0
7486         set_checksums 0
7487
7488         cancel_lru_locks osc
7489         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
7490         do_facet ost1 lctl set_param fail_loc=0x8000021b
7491         set_checksums 1
7492         cmp $F77_TMP $file || error "file compare failed"
7493         do_facet ost1 lctl set_param fail_loc=0
7494         set_checksums 0
7495 }
7496 run_test 77g "checksum error on OST write, read"
7497
7498 test_77k() { # LU-10906
7499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7500         $GSS && skip_env "could not run with gss"
7501
7502         local cksum_param="osc.$FSNAME*.checksums"
7503         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
7504         local checksum
7505         local i
7506
7507         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
7508         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
7509         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
7510                 EXIT
7511
7512         for i in 0 1; do
7513                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
7514                         error "failed to set checksum=$i on MGS"
7515                 wait_update $HOSTNAME "$get_checksum" $i
7516                 #remount
7517                 echo "remount client, checksum should be $i"
7518                 remount_client $MOUNT || "failed to remount client"
7519                 checksum=$(eval $get_checksum)
7520                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7521         done
7522         # remove persistent param to avoid races with checksum mountopt below
7523         do_facet mgs $LCTL set_param -P -d $cksum_param ||
7524                 error "failed to delete checksum on MGS"
7525
7526         for opt in "checksum" "nochecksum"; do
7527                 #remount with mount option
7528                 echo "remount client with option $opt, checksum should be $i"
7529                 umount_client $MOUNT || "failed to umount client"
7530                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
7531                         "failed to mount client with option '$opt'"
7532                 checksum=$(eval $get_checksum)
7533                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7534                 i=$((i - 1))
7535         done
7536
7537         remount_client $MOUNT || "failed to remount client"
7538 }
7539 run_test 77k "enable/disable checksum correctly"
7540
7541 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
7542 rm -f $F77_TMP
7543 unset F77_TMP
7544
7545 cleanup_test_78() {
7546         trap 0
7547         rm -f $DIR/$tfile
7548 }
7549
7550 test_78() { # bug 10901
7551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7552         remote_ost || skip_env "local OST"
7553
7554         NSEQ=5
7555         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
7556         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
7557         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
7558         echo "MemTotal: $MEMTOTAL"
7559
7560         # reserve 256MB of memory for the kernel and other running processes,
7561         # and then take 1/2 of the remaining memory for the read/write buffers.
7562         if [ $MEMTOTAL -gt 512 ] ;then
7563                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
7564         else
7565                 # for those poor memory-starved high-end clusters...
7566                 MEMTOTAL=$((MEMTOTAL / 2))
7567         fi
7568         echo "Mem to use for directio: $MEMTOTAL"
7569
7570         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
7571         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
7572         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
7573         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
7574                 head -n1)
7575         echo "Smallest OST: $SMALLESTOST"
7576         [[ $SMALLESTOST -lt 10240 ]] &&
7577                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
7578
7579         trap cleanup_test_78 EXIT
7580
7581         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
7582                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
7583
7584         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
7585         echo "File size: $F78SIZE"
7586         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
7587         for i in $(seq 1 $NSEQ); do
7588                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
7589                 echo directIO rdwr round $i of $NSEQ
7590                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
7591         done
7592
7593         cleanup_test_78
7594 }
7595 run_test 78 "handle large O_DIRECT writes correctly ============"
7596
7597 test_79() { # bug 12743
7598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7599
7600         wait_delete_completed
7601
7602         BKTOTAL=$(calc_osc_kbytes kbytestotal)
7603         BKFREE=$(calc_osc_kbytes kbytesfree)
7604         BKAVAIL=$(calc_osc_kbytes kbytesavail)
7605
7606         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
7607         DFTOTAL=`echo $STRING | cut -d, -f1`
7608         DFUSED=`echo $STRING  | cut -d, -f2`
7609         DFAVAIL=`echo $STRING | cut -d, -f3`
7610         DFFREE=$(($DFTOTAL - $DFUSED))
7611
7612         ALLOWANCE=$((64 * $OSTCOUNT))
7613
7614         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
7615            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
7616                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
7617         fi
7618         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
7619            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
7620                 error "df free($DFFREE) mismatch OST free($BKFREE)"
7621         fi
7622         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
7623            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
7624                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
7625         fi
7626 }
7627 run_test 79 "df report consistency check ======================="
7628
7629 test_80() { # bug 10718
7630         remote_ost_nodsh && skip "remote OST with nodsh"
7631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7632
7633         # relax strong synchronous semantics for slow backends like ZFS
7634         local soc="obdfilter.*.sync_on_lock_cancel"
7635         local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
7636         local hosts=
7637         if [ "$soc_old" != "never" ] &&
7638                 [ "$ost1_FSTYPE" != "ldiskfs" ]; then
7639                         hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
7640                                 facet_active_host $host; done | sort -u)
7641                         do_nodes $hosts lctl set_param $soc=never
7642         fi
7643
7644         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
7645         sync; sleep 1; sync
7646         local BEFORE=`date +%s`
7647         cancel_lru_locks osc
7648         local AFTER=`date +%s`
7649         local DIFF=$((AFTER-BEFORE))
7650         if [ $DIFF -gt 1 ] ; then
7651                 error "elapsed for 1M@1T = $DIFF"
7652         fi
7653
7654         [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
7655
7656         rm -f $DIR/$tfile
7657 }
7658 run_test 80 "Page eviction is equally fast at high offsets too  ===="
7659
7660 test_81a() { # LU-456
7661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7662         remote_ost_nodsh && skip "remote OST with nodsh"
7663
7664         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
7665         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
7666         do_facet ost1 lctl set_param fail_loc=0x80000228
7667
7668         # write should trigger a retry and success
7669         $LFS setstripe -i 0 -c 1 $DIR/$tfile
7670         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
7671         RC=$?
7672         if [ $RC -ne 0 ] ; then
7673                 error "write should success, but failed for $RC"
7674         fi
7675 }
7676 run_test 81a "OST should retry write when get -ENOSPC ==============="
7677
7678 test_81b() { # LU-456
7679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7680         remote_ost_nodsh && skip "remote OST with nodsh"
7681
7682         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
7683         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
7684         do_facet ost1 lctl set_param fail_loc=0x228
7685
7686         # write should retry several times and return -ENOSPC finally
7687         $LFS setstripe -i 0 -c 1 $DIR/$tfile
7688         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
7689         RC=$?
7690         ENOSPC=28
7691         if [ $RC -ne $ENOSPC ] ; then
7692                 error "dd should fail for -ENOSPC, but succeed."
7693         fi
7694 }
7695 run_test 81b "OST should return -ENOSPC when retry still fails ======="
7696
7697 test_82() { # LU-1031
7698         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
7699         local gid1=14091995
7700         local gid2=16022000
7701
7702         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
7703         local MULTIPID1=$!
7704         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
7705         local MULTIPID2=$!
7706         kill -USR1 $MULTIPID2
7707         sleep 2
7708         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
7709                 error "First grouplock does not block second one"
7710         else
7711                 echo "Second grouplock blocks first one"
7712         fi
7713         kill -USR1 $MULTIPID1
7714         wait $MULTIPID1
7715         wait $MULTIPID2
7716 }
7717 run_test 82 "Basic grouplock test"
7718
7719 test_99() {
7720         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
7721
7722         test_mkdir $DIR/$tdir.cvsroot
7723         chown $RUNAS_ID $DIR/$tdir.cvsroot
7724
7725         cd $TMP
7726         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
7727
7728         cd /etc/init.d
7729         # some versions of cvs import exit(1) when asked to import links or
7730         # files they can't read.  ignore those files.
7731         local toignore=$(find . -type l -printf '-I %f\n' -o \
7732                          ! -perm /4 -printf '-I %f\n')
7733         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
7734                 $tdir.reposname vtag rtag
7735
7736         cd $DIR
7737         test_mkdir $DIR/$tdir.reposname
7738         chown $RUNAS_ID $DIR/$tdir.reposname
7739         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
7740
7741         cd $DIR/$tdir.reposname
7742         $RUNAS touch foo99
7743         $RUNAS cvs add -m 'addmsg' foo99
7744         $RUNAS cvs update
7745         $RUNAS cvs commit -m 'nomsg' foo99
7746         rm -fr $DIR/$tdir.cvsroot
7747 }
7748 run_test 99 "cvs strange file/directory operations"
7749
7750 test_100() {
7751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7752         [[ "$NETTYPE" =~ tcp ]] ||
7753                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
7754         remote_ost_nodsh && skip "remote OST with nodsh"
7755         remote_mds_nodsh && skip "remote MDS with nodsh"
7756         remote_servers ||
7757                 skip "useless for local single node setup"
7758
7759         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
7760                 [ "$PROT" != "tcp" ] && continue
7761                 RPORT=$(echo $REMOTE | cut -d: -f2)
7762                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
7763
7764                 rc=0
7765                 LPORT=`echo $LOCAL | cut -d: -f2`
7766                 if [ $LPORT -ge 1024 ]; then
7767                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
7768                         netstat -tna
7769                         error_exit "local: $LPORT > 1024, remote: $RPORT"
7770                 fi
7771         done
7772         [ "$rc" = 0 ] || error_exit "privileged port not found" )
7773 }
7774 run_test 100 "check local port using privileged port ==========="
7775
7776 function get_named_value()
7777 {
7778     local tag
7779
7780     tag=$1
7781     while read ;do
7782         line=$REPLY
7783         case $line in
7784         $tag*)
7785             echo $line | sed "s/^$tag[ ]*//"
7786             break
7787             ;;
7788         esac
7789     done
7790 }
7791
7792 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
7793                    awk '/^max_cached_mb/ { print $2 }')
7794
7795 cleanup_101a() {
7796         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
7797         trap 0
7798 }
7799
7800 test_101a() {
7801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7802         [ $MDSCOUNT -ge 2 ] && skip_env "needs < 2 MDTs" #LU-4322
7803
7804         local s
7805         local discard
7806         local nreads=10000
7807         local cache_limit=32
7808
7809         $LCTL set_param -n osc.*-osc*.rpc_stats 0
7810         trap cleanup_101a EXIT
7811         $LCTL set_param -n llite.*.read_ahead_stats 0
7812         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
7813
7814         #
7815         # randomly read 10000 of 64K chunks from file 3x 32MB in size
7816         #
7817         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
7818         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
7819
7820         discard=0
7821         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
7822                 get_named_value 'read but discarded' | cut -d" " -f1); do
7823                         discard=$(($discard + $s))
7824         done
7825         cleanup_101a
7826
7827         if [[ $(($discard * 10)) -gt $nreads ]]; then
7828                 $LCTL get_param osc.*-osc*.rpc_stats
7829                 $LCTL get_param llite.*.read_ahead_stats
7830                 error "too many ($discard) discarded pages"
7831         fi
7832         rm -f $DIR/$tfile || true
7833 }
7834 run_test 101a "check read-ahead for random reads"
7835
7836 setup_test101bc() {
7837         test_mkdir $DIR/$tdir
7838         local ssize=$1
7839         local FILE_LENGTH=$2
7840         STRIPE_OFFSET=0
7841
7842         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
7843
7844         local list=$(comma_list $(osts_nodes))
7845         set_osd_param $list '' read_cache_enable 0
7846         set_osd_param $list '' writethrough_cache_enable 0
7847
7848         trap cleanup_test101bc EXIT
7849         # prepare the read-ahead file
7850         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
7851
7852         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
7853                                 count=$FILE_SIZE_MB 2> /dev/null
7854
7855 }
7856
7857 cleanup_test101bc() {
7858         trap 0
7859         rm -rf $DIR/$tdir
7860         rm -f $DIR/$tfile
7861
7862         local list=$(comma_list $(osts_nodes))
7863         set_osd_param $list '' read_cache_enable 1
7864         set_osd_param $list '' writethrough_cache_enable 1
7865 }
7866
7867 calc_total() {
7868         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
7869 }
7870
7871 ra_check_101() {
7872         local READ_SIZE=$1
7873         local STRIPE_SIZE=$2
7874         local FILE_LENGTH=$3
7875         local RA_INC=1048576
7876         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
7877         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
7878                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
7879         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
7880                         get_named_value 'read but discarded' |
7881                         cut -d" " -f1 | calc_total)
7882         if [[ $DISCARD -gt $discard_limit ]]; then
7883                 $LCTL get_param llite.*.read_ahead_stats
7884                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
7885         else
7886                 echo "Read-ahead success for size ${READ_SIZE}"
7887         fi
7888 }
7889
7890 test_101b() {
7891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7892         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7893
7894         local STRIPE_SIZE=1048576
7895         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
7896
7897         if [ $SLOW == "yes" ]; then
7898                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
7899         else
7900                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
7901         fi
7902
7903         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
7904
7905         # prepare the read-ahead file
7906         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
7907         cancel_lru_locks osc
7908         for BIDX in 2 4 8 16 32 64 128 256
7909         do
7910                 local BSIZE=$((BIDX*4096))
7911                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
7912                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
7913                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
7914                 $LCTL set_param -n llite.*.read_ahead_stats 0
7915                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
7916                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
7917                 cancel_lru_locks osc
7918                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
7919         done
7920         cleanup_test101bc
7921         true
7922 }
7923 run_test 101b "check stride-io mode read-ahead ================="
7924
7925 test_101c() {
7926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7927
7928         local STRIPE_SIZE=1048576
7929         local FILE_LENGTH=$((STRIPE_SIZE*100))
7930         local nreads=10000
7931         local rsize=65536
7932         local osc_rpc_stats
7933
7934         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
7935
7936         cancel_lru_locks osc
7937         $LCTL set_param osc.*.rpc_stats 0
7938         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
7939         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
7940                 local stats=$($LCTL get_param -n $osc_rpc_stats)
7941                 local lines=$(echo "$stats" | awk 'END {print NR;}')
7942                 local size
7943
7944                 if [ $lines -le 20 ]; then
7945                         continue
7946                 fi
7947                 for size in 1 2 4 8; do
7948                         local rpc=$(echo "$stats" |
7949                                     awk '($1 == "'$size':") {print $2; exit; }')
7950                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
7951                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
7952                 done
7953                 echo "$osc_rpc_stats check passed!"
7954         done
7955         cleanup_test101bc
7956         true
7957 }
7958 run_test 101c "check stripe_size aligned read-ahead ================="
7959
7960 set_read_ahead() {
7961         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
7962         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
7963 }
7964
7965 test_101d() {
7966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7967
7968         local file=$DIR/$tfile
7969         local sz_MB=${FILESIZE_101d:-500}
7970         local ra_MB=${READAHEAD_MB:-40}
7971
7972         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
7973         [ $free_MB -lt $sz_MB ] &&
7974                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
7975
7976         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
7977         $LFS setstripe -c -1 $file || error "setstripe failed"
7978
7979         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
7980         echo Cancel LRU locks on lustre client to flush the client cache
7981         cancel_lru_locks osc
7982
7983         echo Disable read-ahead
7984         local old_READAHEAD=$(set_read_ahead 0)
7985
7986         echo Reading the test file $file with read-ahead disabled
7987         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
7988
7989         echo Cancel LRU locks on lustre client to flush the client cache
7990         cancel_lru_locks osc
7991         echo Enable read-ahead with ${ra_MB}MB
7992         set_read_ahead $ra_MB
7993
7994         echo Reading the test file $file with read-ahead enabled
7995         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
7996
7997         echo "read-ahead disabled time read $raOFF"
7998         echo "read-ahead enabled  time read $raON"
7999
8000         set_read_ahead $old_READAHEAD
8001         rm -f $file
8002         wait_delete_completed
8003
8004         [ $raOFF -le 1 ] || [ $raON -lt $raOFF ] ||
8005                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
8006 }
8007 run_test 101d "file read with and without read-ahead enabled"
8008
8009 test_101e() {
8010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8011
8012         local file=$DIR/$tfile
8013         local size_KB=500  #KB
8014         local count=100
8015         local bsize=1024
8016
8017         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
8018         local need_KB=$((count * size_KB))
8019         [[ $free_KB -le $need_KB ]] &&
8020                 skip_env "Need free space $need_KB, have $free_KB"
8021
8022         echo "Creating $count ${size_KB}K test files"
8023         for ((i = 0; i < $count; i++)); do
8024                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
8025         done
8026
8027         echo "Cancel LRU locks on lustre client to flush the client cache"
8028         cancel_lru_locks $OSC
8029
8030         echo "Reset readahead stats"
8031         $LCTL set_param -n llite.*.read_ahead_stats 0
8032
8033         for ((i = 0; i < $count; i++)); do
8034                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
8035         done
8036
8037         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8038                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
8039
8040         for ((i = 0; i < $count; i++)); do
8041                 rm -rf $file.$i 2>/dev/null
8042         done
8043
8044         #10000 means 20% reads are missing in readahead
8045         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
8046 }
8047 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
8048
8049 test_101f() {
8050         which iozone || skip_env "no iozone installed"
8051
8052         local old_debug=$($LCTL get_param debug)
8053         old_debug=${old_debug#*=}
8054         $LCTL set_param debug="reada mmap"
8055
8056         # create a test file
8057         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
8058
8059         echo Cancel LRU locks on lustre client to flush the client cache
8060         cancel_lru_locks osc
8061
8062         echo Reset readahead stats
8063         $LCTL set_param -n llite.*.read_ahead_stats 0
8064
8065         echo mmap read the file with small block size
8066         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
8067                 > /dev/null 2>&1
8068
8069         echo checking missing pages
8070         $LCTL get_param llite.*.read_ahead_stats
8071         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8072                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8073
8074         $LCTL set_param debug="$old_debug"
8075         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
8076         rm -f $DIR/$tfile
8077 }
8078 run_test 101f "check mmap read performance"
8079
8080 test_101g_brw_size_test() {
8081         local mb=$1
8082         local pages=$((mb * 1048576 / PAGE_SIZE))
8083         local file=$DIR/$tfile
8084
8085         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
8086                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
8087         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
8088                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
8089                         return 2
8090         done
8091
8092         stack_trap "rm -f $file" EXIT
8093         $LCTL set_param -n osc.*.rpc_stats=0
8094
8095         # 10 RPCs should be enough for the test
8096         local count=10
8097         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
8098                 { error "dd write ${mb} MB blocks failed"; return 3; }
8099         cancel_lru_locks osc
8100         dd of=/dev/null if=$file bs=${mb}M count=$count ||
8101                 { error "dd write ${mb} MB blocks failed"; return 4; }
8102
8103         # calculate number of full-sized read and write RPCs
8104         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
8105                 sed -n '/pages per rpc/,/^$/p' |
8106                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
8107                 END { print reads,writes }'))
8108         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
8109                 return 5
8110         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
8111                 return 6
8112
8113         return 0
8114 }
8115
8116 test_101g() {
8117         remote_ost_nodsh && skip "remote OST with nodsh"
8118
8119         local rpcs
8120         local osts=$(get_facets OST)
8121         local list=$(comma_list $(osts_nodes))
8122         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8123         local brw_size="obdfilter.*.brw_size"
8124
8125         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8126
8127         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
8128
8129         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
8130                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
8131                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
8132            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
8133                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
8134                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
8135
8136                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
8137                         suffix="M"
8138
8139                 if [[ $orig_mb -lt 16 ]]; then
8140                         save_lustre_params $osts "$brw_size" > $p
8141                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
8142                                 error "set 16MB RPC size failed"
8143
8144                         echo "remount client to enable new RPC size"
8145                         remount_client $MOUNT || error "remount_client failed"
8146                 fi
8147
8148                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
8149                 # should be able to set brw_size=12, but no rpc_stats for that
8150                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
8151         fi
8152
8153         test_101g_brw_size_test 4 || error "4MB RPC test failed"
8154
8155         if [[ $orig_mb -lt 16 ]]; then
8156                 restore_lustre_params < $p
8157                 remount_client $MOUNT || error "remount_client restore failed"
8158         fi
8159
8160         rm -f $p $DIR/$tfile
8161 }
8162 run_test 101g "Big bulk(4/16 MiB) readahead"
8163
8164 setup_test102() {
8165         test_mkdir $DIR/$tdir
8166         chown $RUNAS_ID $DIR/$tdir
8167         STRIPE_SIZE=65536
8168         STRIPE_OFFSET=1
8169         STRIPE_COUNT=$OSTCOUNT
8170         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
8171
8172         trap cleanup_test102 EXIT
8173         cd $DIR
8174         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
8175         cd $DIR/$tdir
8176         for num in 1 2 3 4; do
8177                 for count in $(seq 1 $STRIPE_COUNT); do
8178                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
8179                                 local size=`expr $STRIPE_SIZE \* $num`
8180                                 local file=file"$num-$idx-$count"
8181                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
8182                         done
8183                 done
8184         done
8185
8186         cd $DIR
8187         $1 tar cf $TMP/f102.tar $tdir --xattrs
8188 }
8189
8190 cleanup_test102() {
8191         trap 0
8192         rm -f $TMP/f102.tar
8193         rm -rf $DIR/d0.sanity/d102
8194 }
8195
8196 test_102a() {
8197         [ "$UID" != 0 ] && skip "must run as root"
8198         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
8199                 skip_env "must have user_xattr"
8200
8201         [ -z "$(which setfattr 2>/dev/null)" ] &&
8202                 skip_env "could not find setfattr"
8203
8204         local testfile=$DIR/$tfile
8205
8206         touch $testfile
8207         echo "set/get xattr..."
8208         setfattr -n trusted.name1 -v value1 $testfile ||
8209                 error "setfattr -n trusted.name1=value1 $testfile failed"
8210         getfattr -n trusted.name1 $testfile 2> /dev/null |
8211           grep "trusted.name1=.value1" ||
8212                 error "$testfile missing trusted.name1=value1"
8213
8214         setfattr -n user.author1 -v author1 $testfile ||
8215                 error "setfattr -n user.author1=author1 $testfile failed"
8216         getfattr -n user.author1 $testfile 2> /dev/null |
8217           grep "user.author1=.author1" ||
8218                 error "$testfile missing trusted.author1=author1"
8219
8220         echo "listxattr..."
8221         setfattr -n trusted.name2 -v value2 $testfile ||
8222                 error "$testfile unable to set trusted.name2"
8223         setfattr -n trusted.name3 -v value3 $testfile ||
8224                 error "$testfile unable to set trusted.name3"
8225         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
8226             grep "trusted.name" | wc -l) -eq 3 ] ||
8227                 error "$testfile missing 3 trusted.name xattrs"
8228
8229         setfattr -n user.author2 -v author2 $testfile ||
8230                 error "$testfile unable to set user.author2"
8231         setfattr -n user.author3 -v author3 $testfile ||
8232                 error "$testfile unable to set user.author3"
8233         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
8234             grep "user.author" | wc -l) -eq 3 ] ||
8235                 error "$testfile missing 3 user.author xattrs"
8236
8237         echo "remove xattr..."
8238         setfattr -x trusted.name1 $testfile ||
8239                 error "$testfile error deleting trusted.name1"
8240         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
8241                 error "$testfile did not delete trusted.name1 xattr"
8242
8243         setfattr -x user.author1 $testfile ||
8244                 error "$testfile error deleting user.author1"
8245         echo "set lustre special xattr ..."
8246         $LFS setstripe -c1 $testfile
8247         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
8248                 awk -F "=" '/trusted.lov/ { print $2 }' )
8249         setfattr -n "trusted.lov" -v $lovea $testfile ||
8250                 error "$testfile doesn't ignore setting trusted.lov again"
8251         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
8252                 error "$testfile allow setting invalid trusted.lov"
8253         rm -f $testfile
8254 }
8255 run_test 102a "user xattr test =================================="
8256
8257 test_102b() {
8258         [ -z "$(which setfattr 2>/dev/null)" ] &&
8259                 skip_env "could not find setfattr"
8260         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8261
8262         # b10930: get/set/list trusted.lov xattr
8263         echo "get/set/list trusted.lov xattr ..."
8264         local testfile=$DIR/$tfile
8265         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8266                 error "setstripe failed"
8267         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
8268                 error "getstripe failed"
8269         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
8270                 error "can't get trusted.lov from $testfile"
8271
8272         local testfile2=${testfile}2
8273         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
8274                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
8275
8276         $MCREATE $testfile2
8277         setfattr -n trusted.lov -v $value $testfile2
8278         local stripe_size=$($LFS getstripe -S $testfile2)
8279         local stripe_count=$($LFS getstripe -c $testfile2)
8280         [[ $stripe_size -eq 65536 ]] ||
8281                 error "stripe size $stripe_size != 65536"
8282         [[ $stripe_count -eq $STRIPECOUNT ]] ||
8283                 error "stripe count $stripe_count != $STRIPECOUNT"
8284         rm -f $DIR/$tfile
8285 }
8286 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
8287
8288 test_102c() {
8289         [ -z "$(which setfattr 2>/dev/null)" ] &&
8290                 skip_env "could not find setfattr"
8291         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8292
8293         # b10930: get/set/list lustre.lov xattr
8294         echo "get/set/list lustre.lov xattr ..."
8295         test_mkdir $DIR/$tdir
8296         chown $RUNAS_ID $DIR/$tdir
8297         local testfile=$DIR/$tdir/$tfile
8298         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8299                 error "setstripe failed"
8300         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
8301                 error "getstripe failed"
8302         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
8303         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
8304
8305         local testfile2=${testfile}2
8306         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
8307                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
8308
8309         $RUNAS $MCREATE $testfile2
8310         $RUNAS setfattr -n lustre.lov -v $value $testfile2
8311         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
8312         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
8313         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
8314         [ $stripe_count -eq $STRIPECOUNT ] ||
8315                 error "stripe count $stripe_count != $STRIPECOUNT"
8316 }
8317 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
8318
8319 compare_stripe_info1() {
8320         local stripe_index_all_zero=true
8321
8322         for num in 1 2 3 4; do
8323                 for count in $(seq 1 $STRIPE_COUNT); do
8324                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
8325                                 local size=$((STRIPE_SIZE * num))
8326                                 local file=file"$num-$offset-$count"
8327                                 stripe_size=$($LFS getstripe -S $PWD/$file)
8328                                 [[ $stripe_size -ne $size ]] &&
8329                                     error "$file: size $stripe_size != $size"
8330                                 stripe_count=$($LFS getstripe -c $PWD/$file)
8331                                 # allow fewer stripes to be created, ORI-601
8332                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
8333                                     error "$file: count $stripe_count != $count"
8334                                 stripe_index=$($LFS getstripe -i $PWD/$file)
8335                                 [[ $stripe_index -ne 0 ]] &&
8336                                         stripe_index_all_zero=false
8337                         done
8338                 done
8339         done
8340         $stripe_index_all_zero &&
8341                 error "all files are being extracted starting from OST index 0"
8342         return 0
8343 }
8344
8345 have_xattrs_include() {
8346         tar --help | grep -q xattrs-include &&
8347                 echo --xattrs-include="lustre.*"
8348 }
8349
8350 test_102d() {
8351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8352         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8353
8354         XINC=$(have_xattrs_include)
8355         setup_test102
8356         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8357         cd $DIR/$tdir/$tdir
8358         compare_stripe_info1
8359 }
8360 run_test 102d "tar restore stripe info from tarfile,not keep osts"
8361
8362 test_102f() {
8363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8364         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8365
8366         XINC=$(have_xattrs_include)
8367         setup_test102
8368         test_mkdir $DIR/$tdir.restore
8369         cd $DIR
8370         tar cf - --xattrs $tdir | tar xf - \
8371                 -C $DIR/$tdir.restore --xattrs $XINC
8372         cd $DIR/$tdir.restore/$tdir
8373         compare_stripe_info1
8374 }
8375 run_test 102f "tar copy files, not keep osts"
8376
8377 grow_xattr() {
8378         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
8379                 skip "must have user_xattr"
8380         [ -z "$(which setfattr 2>/dev/null)" ] &&
8381                 skip_env "could not find setfattr"
8382         [ -z "$(which getfattr 2>/dev/null)" ] &&
8383                 skip_env "could not find getfattr"
8384
8385         local xsize=${1:-1024}  # in bytes
8386         local file=$DIR/$tfile
8387         local value="$(generate_string $xsize)"
8388         local xbig=trusted.big
8389         local toobig=$2
8390
8391         touch $file
8392         log "save $xbig on $file"
8393         if [ -z "$toobig" ]
8394         then
8395                 setfattr -n $xbig -v $value $file ||
8396                         error "saving $xbig on $file failed"
8397         else
8398                 setfattr -n $xbig -v $value $file &&
8399                         error "saving $xbig on $file succeeded"
8400                 return 0
8401         fi
8402
8403         local orig=$(get_xattr_value $xbig $file)
8404         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
8405
8406         local xsml=trusted.sml
8407         log "save $xsml on $file"
8408         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
8409
8410         local new=$(get_xattr_value $xbig $file)
8411         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
8412
8413         log "grow $xsml on $file"
8414         setfattr -n $xsml -v "$value" $file ||
8415                 error "growing $xsml on $file failed"
8416
8417         new=$(get_xattr_value $xbig $file)
8418         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
8419         log "$xbig still valid after growing $xsml"
8420
8421         rm -f $file
8422 }
8423
8424 test_102h() { # bug 15777
8425         grow_xattr 1024
8426 }
8427 run_test 102h "grow xattr from inside inode to external block"
8428
8429 test_102ha() {
8430         large_xattr_enabled || skip_env "ea_inode feature disabled"
8431
8432         echo "setting xattr of max xattr size: $(max_xattr_size)"
8433         grow_xattr $(max_xattr_size)
8434
8435         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
8436         echo "This should fail:"
8437         grow_xattr $(($(max_xattr_size) + 10)) 1
8438 }
8439 run_test 102ha "grow xattr from inside inode to external inode"
8440
8441 test_102i() { # bug 17038
8442         [ -z "$(which getfattr 2>/dev/null)" ] &&
8443                 skip "could not find getfattr"
8444
8445         touch $DIR/$tfile
8446         ln -s $DIR/$tfile $DIR/${tfile}link
8447         getfattr -n trusted.lov $DIR/$tfile ||
8448                 error "lgetxattr on $DIR/$tfile failed"
8449         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
8450                 grep -i "no such attr" ||
8451                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
8452         rm -f $DIR/$tfile $DIR/${tfile}link
8453 }
8454 run_test 102i "lgetxattr test on symbolic link ============"
8455
8456 test_102j() {
8457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8458         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8459
8460         XINC=$(have_xattrs_include)
8461         setup_test102 "$RUNAS"
8462         chown $RUNAS_ID $DIR/$tdir
8463         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8464         cd $DIR/$tdir/$tdir
8465         compare_stripe_info1 "$RUNAS"
8466 }
8467 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
8468
8469 test_102k() {
8470         [ -z "$(which setfattr 2>/dev/null)" ] &&
8471                 skip "could not find setfattr"
8472
8473         touch $DIR/$tfile
8474         # b22187 just check that does not crash for regular file.
8475         setfattr -n trusted.lov $DIR/$tfile
8476         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
8477         local test_kdir=$DIR/$tdir
8478         test_mkdir $test_kdir
8479         local default_size=$($LFS getstripe -S $test_kdir)
8480         local default_count=$($LFS getstripe -c $test_kdir)
8481         local default_offset=$($LFS getstripe -i $test_kdir)
8482         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
8483                 error 'dir setstripe failed'
8484         setfattr -n trusted.lov $test_kdir
8485         local stripe_size=$($LFS getstripe -S $test_kdir)
8486         local stripe_count=$($LFS getstripe -c $test_kdir)
8487         local stripe_offset=$($LFS getstripe -i $test_kdir)
8488         [ $stripe_size -eq $default_size ] ||
8489                 error "stripe size $stripe_size != $default_size"
8490         [ $stripe_count -eq $default_count ] ||
8491                 error "stripe count $stripe_count != $default_count"
8492         [ $stripe_offset -eq $default_offset ] ||
8493                 error "stripe offset $stripe_offset != $default_offset"
8494         rm -rf $DIR/$tfile $test_kdir
8495 }
8496 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
8497
8498 test_102l() {
8499         [ -z "$(which getfattr 2>/dev/null)" ] &&
8500                 skip "could not find getfattr"
8501
8502         # LU-532 trusted. xattr is invisible to non-root
8503         local testfile=$DIR/$tfile
8504
8505         touch $testfile
8506
8507         echo "listxattr as user..."
8508         chown $RUNAS_ID $testfile
8509         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
8510             grep -q "trusted" &&
8511                 error "$testfile trusted xattrs are user visible"
8512
8513         return 0;
8514 }
8515 run_test 102l "listxattr size test =================================="
8516
8517 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
8518         local path=$DIR/$tfile
8519         touch $path
8520
8521         listxattr_size_check $path || error "listattr_size_check $path failed"
8522 }
8523 run_test 102m "Ensure listxattr fails on small bufffer ========"
8524
8525 cleanup_test102
8526
8527 getxattr() { # getxattr path name
8528         # Return the base64 encoding of the value of xattr name on path.
8529         local path=$1
8530         local name=$2
8531
8532         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
8533         # file: $path
8534         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8535         #
8536         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8537
8538         getfattr --absolute-names --encoding=base64 --name=$name $path |
8539                 awk -F= -v name=$name '$1 == name {
8540                         print substr($0, index($0, "=") + 1);
8541         }'
8542 }
8543
8544 test_102n() { # LU-4101 mdt: protect internal xattrs
8545         [ -z "$(which setfattr 2>/dev/null)" ] &&
8546                 skip "could not find setfattr"
8547         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
8548         then
8549                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
8550         fi
8551
8552         local file0=$DIR/$tfile.0
8553         local file1=$DIR/$tfile.1
8554         local xattr0=$TMP/$tfile.0
8555         local xattr1=$TMP/$tfile.1
8556         local namelist="lov lma lmv link fid version som hsm"
8557         local name
8558         local value
8559
8560         rm -rf $file0 $file1 $xattr0 $xattr1
8561         touch $file0 $file1
8562
8563         # Get 'before' xattrs of $file1.
8564         getfattr --absolute-names --dump --match=- $file1 > $xattr0
8565
8566         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
8567                 namelist+=" lfsck_namespace"
8568         for name in $namelist; do
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                 if [[ x$name == "xlov" ]]; then
8579                         setfattr --name=trusted.lov --value="$value" $file1 &&
8580                         error "setxattr invalid 'trusted.lov' success"
8581                 else
8582                         setfattr --name=trusted.$name --value="$value" $file1 ||
8583                                 error "setxattr invalid 'trusted.$name' failed"
8584                 fi
8585
8586                 # Try to remove the xattr from $file1. We don't care if this
8587                 # appears to succeed or fail, we just don't want there to be
8588                 # any changes or crashes.
8589                 setfattr --remove=$trusted.$name $file1 2> /dev/null
8590         done
8591
8592         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
8593         then
8594                 name="lfsck_ns"
8595                 # Try to copy xattr from $file0 to $file1.
8596                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
8597
8598                 setfattr --name=trusted.$name --value="$value" $file1 ||
8599                         error "setxattr 'trusted.$name' failed"
8600
8601                 # Try to set a garbage xattr.
8602                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
8603
8604                 setfattr --name=trusted.$name --value="$value" $file1 ||
8605                         error "setxattr 'trusted.$name' failed"
8606
8607                 # Try to remove the xattr from $file1. We don't care if this
8608                 # appears to succeed or fail, we just don't want there to be
8609                 # any changes or crashes.
8610                 setfattr --remove=$trusted.$name $file1 2> /dev/null
8611         fi
8612
8613         # Get 'after' xattrs of file1.
8614         getfattr --absolute-names --dump --match=- $file1 > $xattr1
8615
8616         if ! diff $xattr0 $xattr1; then
8617                 error "before and after xattrs of '$file1' differ"
8618         fi
8619
8620         rm -rf $file0 $file1 $xattr0 $xattr1
8621
8622         return 0
8623 }
8624 run_test 102n "silently ignore setxattr on internal trusted xattrs"
8625
8626 test_102p() { # LU-4703 setxattr did not check ownership
8627         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
8628                 skip "MDS needs to be at least 2.5.56"
8629
8630         local testfile=$DIR/$tfile
8631
8632         touch $testfile
8633
8634         echo "setfacl as user..."
8635         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
8636         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
8637
8638         echo "setfattr as user..."
8639         setfacl -m "u:$RUNAS_ID:---" $testfile
8640         $RUNAS setfattr -x system.posix_acl_access $testfile
8641         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
8642 }
8643 run_test 102p "check setxattr(2) correctly fails without permission"
8644
8645 test_102q() {
8646         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
8647                 skip "MDS needs to be at least 2.6.92"
8648
8649         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
8650 }
8651 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
8652
8653 test_102r() {
8654         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
8655                 skip "MDS needs to be at least 2.6.93"
8656
8657         touch $DIR/$tfile || error "touch"
8658         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
8659         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
8660         rm $DIR/$tfile || error "rm"
8661
8662         #normal directory
8663         mkdir -p $DIR/$tdir || error "mkdir"
8664         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
8665         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
8666         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
8667                 error "$testfile error deleting user.author1"
8668         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
8669                 grep "user.$(basename $tdir)" &&
8670                 error "$tdir did not delete user.$(basename $tdir)"
8671         rmdir $DIR/$tdir || error "rmdir"
8672
8673         #striped directory
8674         test_mkdir $DIR/$tdir
8675         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
8676         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
8677         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
8678                 error "$testfile error deleting user.author1"
8679         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
8680                 grep "user.$(basename $tdir)" &&
8681                 error "$tdir did not delete user.$(basename $tdir)"
8682         rmdir $DIR/$tdir || error "rm striped dir"
8683 }
8684 run_test 102r "set EAs with empty values"
8685
8686 test_102s() {
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                 rm -f $DIR/$tfile
8698                 touch $DIR/$tfile || error "touch"
8699                 for prefix in lustre security system trusted user; do
8700                         # Note getxattr() may fail with 'Operation not
8701                         # supported' or 'No such attribute' depending
8702                         # on prefix and cache.
8703                         getfattr -n $prefix.n102s $DIR/$tfile &&
8704                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
8705                 done
8706         done
8707
8708         restore_lustre_params < $save
8709 }
8710 run_test 102s "getting nonexistent xattrs should fail"
8711
8712 test_102t() {
8713         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
8714                 skip "MDS needs to be at least 2.11.52"
8715
8716         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
8717
8718         save_lustre_params client "llite.*.xattr_cache" > $save
8719
8720         for cache in 0 1; do
8721                 lctl set_param llite.*.xattr_cache=$cache
8722
8723                 for buf_size in 0 256; do
8724                         rm -f $DIR/$tfile
8725                         touch $DIR/$tfile || error "touch"
8726                         setfattr -n user.multiop $DIR/$tfile
8727                         $MULTIOP $DIR/$tfile oa$buf_size ||
8728                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
8729                 done
8730         done
8731
8732         restore_lustre_params < $save
8733 }
8734 run_test 102t "zero length xattr values handled correctly"
8735
8736 run_acl_subtest()
8737 {
8738     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
8739     return $?
8740 }
8741
8742 test_103a() {
8743         [ "$UID" != 0 ] && skip "must run as root"
8744         $GSS && skip_env "could not run under gss"
8745         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
8746                 skip_env "must have acl enabled"
8747         [ -z "$(which setfacl 2>/dev/null)" ] &&
8748                 skip_env "could not find setfacl"
8749         remote_mds_nodsh && skip "remote MDS with nodsh"
8750
8751         gpasswd -a daemon bin                           # LU-5641
8752         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
8753
8754         declare -a identity_old
8755
8756         for num in $(seq $MDSCOUNT); do
8757                 switch_identity $num true || identity_old[$num]=$?
8758         done
8759
8760         SAVE_UMASK=$(umask)
8761         umask 0022
8762         mkdir -p $DIR/$tdir
8763         cd $DIR/$tdir
8764
8765         echo "performing cp ..."
8766         run_acl_subtest cp || error "run_acl_subtest cp failed"
8767         echo "performing getfacl-noacl..."
8768         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
8769         echo "performing misc..."
8770         run_acl_subtest misc || error  "misc test failed"
8771         echo "performing permissions..."
8772         run_acl_subtest permissions || error "permissions failed"
8773         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
8774         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
8775                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
8776                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
8777         then
8778                 echo "performing permissions xattr..."
8779                 run_acl_subtest permissions_xattr ||
8780                         error "permissions_xattr failed"
8781         fi
8782         echo "performing setfacl..."
8783         run_acl_subtest setfacl || error  "setfacl test failed"
8784
8785         # inheritance test got from HP
8786         echo "performing inheritance..."
8787         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
8788         chmod +x make-tree || error "chmod +x failed"
8789         run_acl_subtest inheritance || error "inheritance test failed"
8790         rm -f make-tree
8791
8792         echo "LU-974 ignore umask when acl is enabled..."
8793         run_acl_subtest 974 || error "LU-974 umask test failed"
8794         if [ $MDSCOUNT -ge 2 ]; then
8795                 run_acl_subtest 974_remote ||
8796                         error "LU-974 umask test failed under remote dir"
8797         fi
8798
8799         echo "LU-2561 newly created file is same size as directory..."
8800         if [ "$mds1_FSTYPE" != "zfs" ]; then
8801                 run_acl_subtest 2561 || error "LU-2561 test failed"
8802         else
8803                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
8804         fi
8805
8806         run_acl_subtest 4924 || error "LU-4924 test failed"
8807
8808         cd $SAVE_PWD
8809         umask $SAVE_UMASK
8810
8811         for num in $(seq $MDSCOUNT); do
8812                 if [ "${identity_old[$num]}" = 1 ]; then
8813                         switch_identity $num false || identity_old[$num]=$?
8814                 fi
8815         done
8816 }
8817 run_test 103a "acl test"
8818
8819 test_103b() {
8820         declare -a pids
8821         local U
8822
8823         for U in {0..511}; do
8824                 {
8825                 local O=$(printf "%04o" $U)
8826
8827                 umask $(printf "%04o" $((511 ^ $O)))
8828                 $LFS setstripe -c 1 $DIR/$tfile.s$O
8829                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
8830
8831                 (( $S == ($O & 0666) )) ||
8832                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
8833
8834                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
8835                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
8836                 (( $S == ($O & 0666) )) ||
8837                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
8838
8839                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
8840                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
8841                 (( $S == ($O & 0666) )) ||
8842                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
8843                 rm -f $DIR/$tfile.[smp]$0
8844                 } &
8845                 local pid=$!
8846
8847                 # limit the concurrently running threads to 64. LU-11878
8848                 local idx=$((U % 64))
8849                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
8850                 pids[idx]=$pid
8851         done
8852         wait
8853 }
8854 run_test 103b "umask lfs setstripe"
8855
8856 test_103c() {
8857         mkdir -p $DIR/$tdir
8858         cp -rp $DIR/$tdir $DIR/$tdir.bak
8859
8860         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
8861                 error "$DIR/$tdir shouldn't contain default ACL"
8862         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
8863                 error "$DIR/$tdir.bak shouldn't contain default ACL"
8864         true
8865 }
8866 run_test 103c "'cp -rp' won't set empty acl"
8867
8868 test_104a() {
8869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8870
8871         touch $DIR/$tfile
8872         lfs df || error "lfs df failed"
8873         lfs df -ih || error "lfs df -ih failed"
8874         lfs df -h $DIR || error "lfs df -h $DIR failed"
8875         lfs df -i $DIR || error "lfs df -i $DIR failed"
8876         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
8877         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
8878
8879         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
8880         lctl --device %$OSC deactivate
8881         lfs df || error "lfs df with deactivated OSC failed"
8882         lctl --device %$OSC activate
8883         # wait the osc back to normal
8884         wait_osc_import_ready client ost
8885
8886         lfs df || error "lfs df with reactivated OSC failed"
8887         rm -f $DIR/$tfile
8888 }
8889 run_test 104a "lfs df [-ih] [path] test ========================="
8890
8891 test_104b() {
8892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8893         [ $RUNAS_ID -eq $UID ] &&
8894                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8895
8896         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
8897                         grep "Permission denied" | wc -l)))
8898         if [ $denied_cnt -ne 0 ]; then
8899                 error "lfs check servers test failed"
8900         fi
8901 }
8902 run_test 104b "$RUNAS lfs check servers test ===================="
8903
8904 test_105a() {
8905         # doesn't work on 2.4 kernels
8906         touch $DIR/$tfile
8907         if $(flock_is_enabled); then
8908                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
8909         else
8910                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
8911         fi
8912         rm -f $DIR/$tfile
8913 }
8914 run_test 105a "flock when mounted without -o flock test ========"
8915
8916 test_105b() {
8917         touch $DIR/$tfile
8918         if $(flock_is_enabled); then
8919                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
8920         else
8921                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
8922         fi
8923         rm -f $DIR/$tfile
8924 }
8925 run_test 105b "fcntl when mounted without -o flock test ========"
8926
8927 test_105c() {
8928         touch $DIR/$tfile
8929         if $(flock_is_enabled); then
8930                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
8931         else
8932                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
8933         fi
8934         rm -f $DIR/$tfile
8935 }
8936 run_test 105c "lockf when mounted without -o flock test"
8937
8938 test_105d() { # bug 15924
8939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8940
8941         test_mkdir $DIR/$tdir
8942         flock_is_enabled || skip_env "mount w/o flock enabled"
8943         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
8944         $LCTL set_param fail_loc=0x80000315
8945         flocks_test 2 $DIR/$tdir
8946 }
8947 run_test 105d "flock race (should not freeze) ========"
8948
8949 test_105e() { # bug 22660 && 22040
8950         flock_is_enabled || skip_env "mount w/o flock enabled"
8951
8952         touch $DIR/$tfile
8953         flocks_test 3 $DIR/$tfile
8954 }
8955 run_test 105e "Two conflicting flocks from same process"
8956
8957 test_106() { #bug 10921
8958         test_mkdir $DIR/$tdir
8959         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
8960         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
8961 }
8962 run_test 106 "attempt exec of dir followed by chown of that dir"
8963
8964 test_107() {
8965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8966
8967         CDIR=`pwd`
8968         local file=core
8969
8970         cd $DIR
8971         rm -f $file
8972
8973         local save_pattern=$(sysctl -n kernel.core_pattern)
8974         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
8975         sysctl -w kernel.core_pattern=$file
8976         sysctl -w kernel.core_uses_pid=0
8977
8978         ulimit -c unlimited
8979         sleep 60 &
8980         SLEEPPID=$!
8981
8982         sleep 1
8983
8984         kill -s 11 $SLEEPPID
8985         wait $SLEEPPID
8986         if [ -e $file ]; then
8987                 size=`stat -c%s $file`
8988                 [ $size -eq 0 ] && error "Fail to create core file $file"
8989         else
8990                 error "Fail to create core file $file"
8991         fi
8992         rm -f $file
8993         sysctl -w kernel.core_pattern=$save_pattern
8994         sysctl -w kernel.core_uses_pid=$save_uses_pid
8995         cd $CDIR
8996 }
8997 run_test 107 "Coredump on SIG"
8998
8999 test_110() {
9000         test_mkdir $DIR/$tdir
9001         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
9002         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
9003                 error "mkdir with 256 char should fail, but did not"
9004         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
9005                 error "create with 255 char failed"
9006         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
9007                 error "create with 256 char should fail, but did not"
9008
9009         ls -l $DIR/$tdir
9010         rm -rf $DIR/$tdir
9011 }
9012 run_test 110 "filename length checking"
9013
9014 #
9015 # Purpose: To verify dynamic thread (OSS) creation.
9016 #
9017 test_115() {
9018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9019         remote_ost_nodsh && skip "remote OST with nodsh"
9020
9021         # Lustre does not stop service threads once they are started.
9022         # Reset number of running threads to default.
9023         stopall
9024         setupall
9025
9026         local OSTIO_pre
9027         local save_params="$TMP/sanity-$TESTNAME.parameters"
9028
9029         # Get ll_ost_io count before I/O
9030         OSTIO_pre=$(do_facet ost1 \
9031                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
9032         # Exit if lustre is not running (ll_ost_io not running).
9033         [ -z "$OSTIO_pre" ] && error "no OSS threads"
9034
9035         echo "Starting with $OSTIO_pre threads"
9036         local thread_max=$((OSTIO_pre * 2))
9037         local rpc_in_flight=$((thread_max * 2))
9038         # Number of I/O Process proposed to be started.
9039         local nfiles
9040         local facets=$(get_facets OST)
9041
9042         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
9043         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
9044
9045         # Set in_flight to $rpc_in_flight
9046         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
9047                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
9048         nfiles=${rpc_in_flight}
9049         # Set ost thread_max to $thread_max
9050         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
9051
9052         # 5 Minutes should be sufficient for max number of OSS
9053         # threads(thread_max) to be created.
9054         local timeout=300
9055
9056         # Start I/O.
9057         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
9058         test_mkdir $DIR/$tdir
9059         for i in $(seq $nfiles); do
9060                 local file=$DIR/$tdir/${tfile}-$i
9061                 $LFS setstripe -c -1 -i 0 $file
9062                 ($WTL $file $timeout)&
9063         done
9064
9065         # I/O Started - Wait for thread_started to reach thread_max or report
9066         # error if thread_started is more than thread_max.
9067         echo "Waiting for thread_started to reach thread_max"
9068         local thread_started=0
9069         local end_time=$((SECONDS + timeout))
9070
9071         while [ $SECONDS -le $end_time ] ; do
9072                 echo -n "."
9073                 # Get ost i/o thread_started count.
9074                 thread_started=$(do_facet ost1 \
9075                         "$LCTL get_param \
9076                         ost.OSS.ost_io.threads_started | cut -d= -f2")
9077                 # Break out if thread_started is equal/greater than thread_max
9078                 if [[ $thread_started -ge $thread_max ]]; then
9079                         echo ll_ost_io thread_started $thread_started, \
9080                                 equal/greater than thread_max $thread_max
9081                         break
9082                 fi
9083                 sleep 1
9084         done
9085
9086         # Cleanup - We have the numbers, Kill i/o jobs if running.
9087         jobcount=($(jobs -p))
9088         for i in $(seq 0 $((${#jobcount[@]}-1)))
9089         do
9090                 kill -9 ${jobcount[$i]}
9091                 if [ $? -ne 0 ] ; then
9092                         echo Warning: \
9093                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
9094                 fi
9095         done
9096
9097         # Cleanup files left by WTL binary.
9098         for i in $(seq $nfiles); do
9099                 local file=$DIR/$tdir/${tfile}-$i
9100                 rm -rf $file
9101                 if [ $? -ne 0 ] ; then
9102                         echo "Warning: Failed to delete file $file"
9103                 fi
9104         done
9105
9106         restore_lustre_params <$save_params
9107         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
9108
9109         # Error out if no new thread has started or Thread started is greater
9110         # than thread max.
9111         if [[ $thread_started -le $OSTIO_pre ||
9112                         $thread_started -gt $thread_max ]]; then
9113                 error "ll_ost_io: thread_started $thread_started" \
9114                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
9115                       "No new thread started or thread started greater " \
9116                       "than thread_max."
9117         fi
9118 }
9119 run_test 115 "verify dynamic thread creation===================="
9120
9121 free_min_max () {
9122         wait_delete_completed
9123         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
9124         echo "OST kbytes available: ${AVAIL[@]}"
9125         MAXV=${AVAIL[0]}
9126         MAXI=0
9127         MINV=${AVAIL[0]}
9128         MINI=0
9129         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
9130                 #echo OST $i: ${AVAIL[i]}kb
9131                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
9132                         MAXV=${AVAIL[i]}
9133                         MAXI=$i
9134                 fi
9135                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
9136                         MINV=${AVAIL[i]}
9137                         MINI=$i
9138                 fi
9139         done
9140         echo "Min free space: OST $MINI: $MINV"
9141         echo "Max free space: OST $MAXI: $MAXV"
9142 }
9143
9144 test_116a() { # was previously test_116()
9145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9146         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9147         remote_mds_nodsh && skip "remote MDS with nodsh"
9148
9149         echo -n "Free space priority "
9150         do_facet $SINGLEMDS lctl get_param -n lo*.*-mdtlov.qos_prio_free |
9151                 head -n1
9152         declare -a AVAIL
9153         free_min_max
9154
9155         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
9156         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
9157         trap simple_cleanup_common EXIT
9158
9159         # Check if we need to generate uneven OSTs
9160         test_mkdir -p $DIR/$tdir/OST${MINI}
9161         local FILL=$((MINV / 4))
9162         local DIFF=$((MAXV - MINV))
9163         local DIFF2=$((DIFF * 100 / MINV))
9164
9165         local threshold=$(do_facet $SINGLEMDS \
9166                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
9167         threshold=${threshold%%%}
9168         echo -n "Check for uneven OSTs: "
9169         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
9170
9171         if [[ $DIFF2 -gt $threshold ]]; then
9172                 echo "ok"
9173                 echo "Don't need to fill OST$MINI"
9174         else
9175                 # generate uneven OSTs. Write 2% over the QOS threshold value
9176                 echo "no"
9177                 DIFF=$((threshold - DIFF2 + 2))
9178                 DIFF2=$((MINV * DIFF / 100))
9179                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
9180                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
9181                         error "setstripe failed"
9182                 DIFF=$((DIFF2 / 2048))
9183                 i=0
9184                 while [ $i -lt $DIFF ]; do
9185                         i=$((i + 1))
9186                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
9187                                 bs=2M count=1 2>/dev/null
9188                         echo -n .
9189                 done
9190                 echo .
9191                 sync
9192                 sleep_maxage
9193                 free_min_max
9194         fi
9195
9196         DIFF=$((MAXV - MINV))
9197         DIFF2=$((DIFF * 100 / MINV))
9198         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
9199         if [ $DIFF2 -gt $threshold ]; then
9200                 echo "ok"
9201         else
9202                 echo "failed - QOS mode won't be used"
9203                 simple_cleanup_common
9204                 skip "QOS imbalance criteria not met"
9205         fi
9206
9207         MINI1=$MINI
9208         MINV1=$MINV
9209         MAXI1=$MAXI
9210         MAXV1=$MAXV
9211
9212         # now fill using QOS
9213         $LFS setstripe -c 1 $DIR/$tdir
9214         FILL=$((FILL / 200))
9215         if [ $FILL -gt 600 ]; then
9216                 FILL=600
9217         fi
9218         echo "writing $FILL files to QOS-assigned OSTs"
9219         i=0
9220         while [ $i -lt $FILL ]; do
9221                 i=$((i + 1))
9222                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
9223                         count=1 2>/dev/null
9224                 echo -n .
9225         done
9226         echo "wrote $i 200k files"
9227         sync
9228         sleep_maxage
9229
9230         echo "Note: free space may not be updated, so measurements might be off"
9231         free_min_max
9232         DIFF2=$((MAXV - MINV))
9233         echo "free space delta: orig $DIFF final $DIFF2"
9234         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
9235         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
9236         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
9237         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
9238         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
9239         if [[ $DIFF -gt 0 ]]; then
9240                 FILL=$((DIFF2 * 100 / DIFF - 100))
9241                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
9242         fi
9243
9244         # Figure out which files were written where
9245         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9246                awk '/'$MINI1': / {print $2; exit}')
9247         echo $UUID
9248         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9249         echo "$MINC files created on smaller OST $MINI1"
9250         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9251                awk '/'$MAXI1': / {print $2; exit}')
9252         echo $UUID
9253         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9254         echo "$MAXC files created on larger OST $MAXI1"
9255         if [[ $MINC -gt 0 ]]; then
9256                 FILL=$((MAXC * 100 / MINC - 100))
9257                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
9258         fi
9259         [[ $MAXC -gt $MINC ]] ||
9260                 error_ignore LU-9 "stripe QOS didn't balance free space"
9261         simple_cleanup_common
9262 }
9263 run_test 116a "stripe QOS: free space balance ==================="
9264
9265 test_116b() { # LU-2093
9266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9267         remote_mds_nodsh && skip "remote MDS with nodsh"
9268
9269 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
9270         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
9271                        lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
9272         [ -z "$old_rr" ] && skip "no QOS"
9273         do_facet $SINGLEMDS lctl set_param \
9274                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
9275         mkdir -p $DIR/$tdir
9276         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
9277         createmany -o $DIR/$tdir/f- 20 || error "can't create"
9278         do_facet $SINGLEMDS lctl set_param fail_loc=0
9279         rm -rf $DIR/$tdir
9280         do_facet $SINGLEMDS lctl set_param \
9281                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
9282 }
9283 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
9284
9285 test_117() # bug 10891
9286 {
9287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9288
9289         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
9290         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
9291         lctl set_param fail_loc=0x21e
9292         > $DIR/$tfile || error "truncate failed"
9293         lctl set_param fail_loc=0
9294         echo "Truncate succeeded."
9295         rm -f $DIR/$tfile
9296 }
9297 run_test 117 "verify osd extend =========="
9298
9299 NO_SLOW_RESENDCOUNT=4
9300 export OLD_RESENDCOUNT=""
9301 set_resend_count () {
9302         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
9303         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
9304         lctl set_param -n $PROC_RESENDCOUNT $1
9305         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
9306 }
9307
9308 # for reduce test_118* time (b=14842)
9309 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9310
9311 # Reset async IO behavior after error case
9312 reset_async() {
9313         FILE=$DIR/reset_async
9314
9315         # Ensure all OSCs are cleared
9316         $LFS setstripe -c -1 $FILE
9317         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
9318         sync
9319         rm $FILE
9320 }
9321
9322 test_118a() #bug 11710
9323 {
9324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9325
9326         reset_async
9327
9328         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9329         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9330         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9331
9332         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9333                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9334                 return 1;
9335         fi
9336         rm -f $DIR/$tfile
9337 }
9338 run_test 118a "verify O_SYNC works =========="
9339
9340 test_118b()
9341 {
9342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9343         remote_ost_nodsh && skip "remote OST with nodsh"
9344
9345         reset_async
9346
9347         #define OBD_FAIL_SRV_ENOENT 0x217
9348         set_nodes_failloc "$(osts_nodes)" 0x217
9349         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9350         RC=$?
9351         set_nodes_failloc "$(osts_nodes)" 0
9352         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9353         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9354                     grep -c writeback)
9355
9356         if [[ $RC -eq 0 ]]; then
9357                 error "Must return error due to dropped pages, rc=$RC"
9358                 return 1;
9359         fi
9360
9361         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9362                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9363                 return 1;
9364         fi
9365
9366         echo "Dirty pages not leaked on ENOENT"
9367
9368         # Due to the above error the OSC will issue all RPCs syncronously
9369         # until a subsequent RPC completes successfully without error.
9370         $MULTIOP $DIR/$tfile Ow4096yc
9371         rm -f $DIR/$tfile
9372
9373         return 0
9374 }
9375 run_test 118b "Reclaim dirty pages on fatal error =========="
9376
9377 test_118c()
9378 {
9379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9380
9381         # for 118c, restore the original resend count, LU-1940
9382         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
9383                                 set_resend_count $OLD_RESENDCOUNT
9384         remote_ost_nodsh && skip "remote OST with nodsh"
9385
9386         reset_async
9387
9388         #define OBD_FAIL_OST_EROFS               0x216
9389         set_nodes_failloc "$(osts_nodes)" 0x216
9390
9391         # multiop should block due to fsync until pages are written
9392         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9393         MULTIPID=$!
9394         sleep 1
9395
9396         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9397                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9398         fi
9399
9400         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9401                     grep -c writeback)
9402         if [[ $WRITEBACK -eq 0 ]]; then
9403                 error "No page in writeback, writeback=$WRITEBACK"
9404         fi
9405
9406         set_nodes_failloc "$(osts_nodes)" 0
9407         wait $MULTIPID
9408         RC=$?
9409         if [[ $RC -ne 0 ]]; then
9410                 error "Multiop fsync failed, rc=$RC"
9411         fi
9412
9413         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9414         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9415                     grep -c writeback)
9416         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9417                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9418         fi
9419
9420         rm -f $DIR/$tfile
9421         echo "Dirty pages flushed via fsync on EROFS"
9422         return 0
9423 }
9424 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
9425
9426 # continue to use small resend count to reduce test_118* time (b=14842)
9427 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9428
9429 test_118d()
9430 {
9431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9432         remote_ost_nodsh && skip "remote OST with nodsh"
9433
9434         reset_async
9435
9436         #define OBD_FAIL_OST_BRW_PAUSE_BULK
9437         set_nodes_failloc "$(osts_nodes)" 0x214
9438         # multiop should block due to fsync until pages are written
9439         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9440         MULTIPID=$!
9441         sleep 1
9442
9443         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9444                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9445         fi
9446
9447         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9448                     grep -c writeback)
9449         if [[ $WRITEBACK -eq 0 ]]; then
9450                 error "No page in writeback, writeback=$WRITEBACK"
9451         fi
9452
9453         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
9454         set_nodes_failloc "$(osts_nodes)" 0
9455
9456         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9457         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9458                     grep -c writeback)
9459         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9460                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9461         fi
9462
9463         rm -f $DIR/$tfile
9464         echo "Dirty pages gaurenteed flushed via fsync"
9465         return 0
9466 }
9467 run_test 118d "Fsync validation inject a delay of the bulk =========="
9468
9469 test_118f() {
9470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9471
9472         reset_async
9473
9474         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
9475         lctl set_param fail_loc=0x8000040a
9476
9477         # Should simulate EINVAL error which is fatal
9478         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9479         RC=$?
9480         if [[ $RC -eq 0 ]]; then
9481                 error "Must return error due to dropped pages, rc=$RC"
9482         fi
9483
9484         lctl set_param fail_loc=0x0
9485
9486         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9487         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9488         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9489                     grep -c writeback)
9490         if [[ $LOCKED -ne 0 ]]; then
9491                 error "Locked pages remain in cache, locked=$LOCKED"
9492         fi
9493
9494         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9495                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9496         fi
9497
9498         rm -f $DIR/$tfile
9499         echo "No pages locked after fsync"
9500
9501         reset_async
9502         return 0
9503 }
9504 run_test 118f "Simulate unrecoverable OSC side error =========="
9505
9506 test_118g() {
9507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9508
9509         reset_async
9510
9511         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9512         lctl set_param fail_loc=0x406
9513
9514         # simulate local -ENOMEM
9515         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9516         RC=$?
9517
9518         lctl set_param fail_loc=0
9519         if [[ $RC -eq 0 ]]; then
9520                 error "Must return error due to dropped pages, rc=$RC"
9521         fi
9522
9523         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9524         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9525         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9526                         grep -c writeback)
9527         if [[ $LOCKED -ne 0 ]]; then
9528                 error "Locked pages remain in cache, locked=$LOCKED"
9529         fi
9530
9531         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9532                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9533         fi
9534
9535         rm -f $DIR/$tfile
9536         echo "No pages locked after fsync"
9537
9538         reset_async
9539         return 0
9540 }
9541 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
9542
9543 test_118h() {
9544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9545         remote_ost_nodsh && skip "remote OST with nodsh"
9546
9547         reset_async
9548
9549         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9550         set_nodes_failloc "$(osts_nodes)" 0x20e
9551         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
9552         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9553         RC=$?
9554
9555         set_nodes_failloc "$(osts_nodes)" 0
9556         if [[ $RC -eq 0 ]]; then
9557                 error "Must return error due to dropped pages, rc=$RC"
9558         fi
9559
9560         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9561         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9562         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9563                     grep -c writeback)
9564         if [[ $LOCKED -ne 0 ]]; then
9565                 error "Locked pages remain in cache, locked=$LOCKED"
9566         fi
9567
9568         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9569                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9570         fi
9571
9572         rm -f $DIR/$tfile
9573         echo "No pages locked after fsync"
9574
9575         return 0
9576 }
9577 run_test 118h "Verify timeout in handling recoverables errors  =========="
9578
9579 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
9580
9581 test_118i() {
9582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9583         remote_ost_nodsh && skip "remote OST with nodsh"
9584
9585         reset_async
9586
9587         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9588         set_nodes_failloc "$(osts_nodes)" 0x20e
9589
9590         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
9591         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9592         PID=$!
9593         sleep 5
9594         set_nodes_failloc "$(osts_nodes)" 0
9595
9596         wait $PID
9597         RC=$?
9598         if [[ $RC -ne 0 ]]; then
9599                 error "got error, but should be not, rc=$RC"
9600         fi
9601
9602         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9603         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9604         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9605         if [[ $LOCKED -ne 0 ]]; then
9606                 error "Locked pages remain in cache, locked=$LOCKED"
9607         fi
9608
9609         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9610                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9611         fi
9612
9613         rm -f $DIR/$tfile
9614         echo "No pages locked after fsync"
9615
9616         return 0
9617 }
9618 run_test 118i "Fix error before timeout in recoverable error  =========="
9619
9620 [ "$SLOW" = "no" ] && set_resend_count 4
9621
9622 test_118j() {
9623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9624         remote_ost_nodsh && skip "remote OST with nodsh"
9625
9626         reset_async
9627
9628         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
9629         set_nodes_failloc "$(osts_nodes)" 0x220
9630
9631         # return -EIO from OST
9632         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9633         RC=$?
9634         set_nodes_failloc "$(osts_nodes)" 0x0
9635         if [[ $RC -eq 0 ]]; then
9636                 error "Must return error due to dropped pages, rc=$RC"
9637         fi
9638
9639         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9640         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9641         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9642         if [[ $LOCKED -ne 0 ]]; then
9643                 error "Locked pages remain in cache, locked=$LOCKED"
9644         fi
9645
9646         # in recoverable error on OST we want resend and stay until it finished
9647         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9648                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9649         fi
9650
9651         rm -f $DIR/$tfile
9652         echo "No pages locked after fsync"
9653
9654         return 0
9655 }
9656 run_test 118j "Simulate unrecoverable OST side error =========="
9657
9658 test_118k()
9659 {
9660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9661         remote_ost_nodsh && skip "remote OSTs with nodsh"
9662
9663         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9664         set_nodes_failloc "$(osts_nodes)" 0x20e
9665         test_mkdir $DIR/$tdir
9666
9667         for ((i=0;i<10;i++)); do
9668                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
9669                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
9670                 SLEEPPID=$!
9671                 sleep 0.500s
9672                 kill $SLEEPPID
9673                 wait $SLEEPPID
9674         done
9675
9676         set_nodes_failloc "$(osts_nodes)" 0
9677         rm -rf $DIR/$tdir
9678 }
9679 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
9680
9681 test_118l() # LU-646
9682 {
9683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9684
9685         test_mkdir $DIR/$tdir
9686         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
9687         rm -rf $DIR/$tdir
9688 }
9689 run_test 118l "fsync dir"
9690
9691 test_118m() # LU-3066
9692 {
9693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9694
9695         test_mkdir $DIR/$tdir
9696         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
9697         rm -rf $DIR/$tdir
9698 }
9699 run_test 118m "fdatasync dir ========="
9700
9701 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
9702
9703 test_118n()
9704 {
9705         local begin
9706         local end
9707
9708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9709         remote_ost_nodsh && skip "remote OSTs with nodsh"
9710
9711         # Sleep to avoid a cached response.
9712         #define OBD_STATFS_CACHE_SECONDS 1
9713         sleep 2
9714
9715         # Inject a 10 second delay in the OST_STATFS handler.
9716         #define OBD_FAIL_OST_STATFS_DELAY 0x242
9717         set_nodes_failloc "$(osts_nodes)" 0x242
9718
9719         begin=$SECONDS
9720         stat --file-system $MOUNT > /dev/null
9721         end=$SECONDS
9722
9723         set_nodes_failloc "$(osts_nodes)" 0
9724
9725         if ((end - begin > 20)); then
9726             error "statfs took $((end - begin)) seconds, expected 10"
9727         fi
9728 }
9729 run_test 118n "statfs() sends OST_STATFS requests in parallel"
9730
9731 test_119a() # bug 11737
9732 {
9733         BSIZE=$((512 * 1024))
9734         directio write $DIR/$tfile 0 1 $BSIZE
9735         # We ask to read two blocks, which is more than a file size.
9736         # directio will indicate an error when requested and actual
9737         # sizes aren't equeal (a normal situation in this case) and
9738         # print actual read amount.
9739         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
9740         if [ "$NOB" != "$BSIZE" ]; then
9741                 error "read $NOB bytes instead of $BSIZE"
9742         fi
9743         rm -f $DIR/$tfile
9744 }
9745 run_test 119a "Short directIO read must return actual read amount"
9746
9747 test_119b() # bug 11737
9748 {
9749         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9750
9751         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
9752         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
9753         sync
9754         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
9755                 error "direct read failed"
9756         rm -f $DIR/$tfile
9757 }
9758 run_test 119b "Sparse directIO read must return actual read amount"
9759
9760 test_119c() # bug 13099
9761 {
9762         BSIZE=1048576
9763         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
9764         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
9765         rm -f $DIR/$tfile
9766 }
9767 run_test 119c "Testing for direct read hitting hole"
9768
9769 test_119d() # bug 15950
9770 {
9771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9772
9773         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
9774         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
9775         BSIZE=1048576
9776         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
9777         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
9778         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
9779         lctl set_param fail_loc=0x40d
9780         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
9781         pid_dio=$!
9782         sleep 1
9783         cat $DIR/$tfile > /dev/null &
9784         lctl set_param fail_loc=0
9785         pid_reads=$!
9786         wait $pid_dio
9787         log "the DIO writes have completed, now wait for the reads (should not block very long)"
9788         sleep 2
9789         [ -n "`ps h -p $pid_reads -o comm`" ] && \
9790         error "the read rpcs have not completed in 2s"
9791         rm -f $DIR/$tfile
9792         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
9793 }
9794 run_test 119d "The DIO path should try to send a new rpc once one is completed"
9795
9796 test_120a() {
9797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9798         remote_mds_nodsh && skip "remote MDS with nodsh"
9799         test_mkdir -i0 -c1 $DIR/$tdir
9800         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9801                 skip_env "no early lock cancel on server"
9802
9803         lru_resize_disable mdc
9804         lru_resize_disable osc
9805         cancel_lru_locks mdc
9806         # asynchronous object destroy at MDT could cause bl ast to client
9807         cancel_lru_locks osc
9808
9809         stat $DIR/$tdir > /dev/null
9810         can1=$(do_facet mds1 \
9811                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9812                awk '/ldlm_cancel/ {print $2}')
9813         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9814                awk '/ldlm_bl_callback/ {print $2}')
9815         test_mkdir -i0 -c1 $DIR/$tdir/d1
9816         can2=$(do_facet mds1 \
9817                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9818                awk '/ldlm_cancel/ {print $2}')
9819         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9820                awk '/ldlm_bl_callback/ {print $2}')
9821         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9822         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9823         lru_resize_enable mdc
9824         lru_resize_enable osc
9825 }
9826 run_test 120a "Early Lock Cancel: mkdir test"
9827
9828 test_120b() {
9829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9830         remote_mds_nodsh && skip "remote MDS with nodsh"
9831         test_mkdir $DIR/$tdir
9832         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9833                 skip_env "no early lock cancel on server"
9834
9835         lru_resize_disable mdc
9836         lru_resize_disable osc
9837         cancel_lru_locks mdc
9838         stat $DIR/$tdir > /dev/null
9839         can1=$(do_facet $SINGLEMDS \
9840                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9841                awk '/ldlm_cancel/ {print $2}')
9842         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9843                awk '/ldlm_bl_callback/ {print $2}')
9844         touch $DIR/$tdir/f1
9845         can2=$(do_facet $SINGLEMDS \
9846                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9847                awk '/ldlm_cancel/ {print $2}')
9848         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9849                awk '/ldlm_bl_callback/ {print $2}')
9850         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9851         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9852         lru_resize_enable mdc
9853         lru_resize_enable osc
9854 }
9855 run_test 120b "Early Lock Cancel: create test"
9856
9857 test_120c() {
9858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9859         remote_mds_nodsh && skip "remote MDS with nodsh"
9860         test_mkdir -i0 -c1 $DIR/$tdir
9861         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9862                 skip "no early lock cancel on server"
9863
9864         lru_resize_disable mdc
9865         lru_resize_disable osc
9866         test_mkdir -i0 -c1 $DIR/$tdir/d1
9867         test_mkdir -i0 -c1 $DIR/$tdir/d2
9868         touch $DIR/$tdir/d1/f1
9869         cancel_lru_locks mdc
9870         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
9871         can1=$(do_facet mds1 \
9872                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9873                awk '/ldlm_cancel/ {print $2}')
9874         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9875                awk '/ldlm_bl_callback/ {print $2}')
9876         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
9877         can2=$(do_facet mds1 \
9878                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9879                awk '/ldlm_cancel/ {print $2}')
9880         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9881                awk '/ldlm_bl_callback/ {print $2}')
9882         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9883         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9884         lru_resize_enable mdc
9885         lru_resize_enable osc
9886 }
9887 run_test 120c "Early Lock Cancel: link test"
9888
9889 test_120d() {
9890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9891         remote_mds_nodsh && skip "remote MDS with nodsh"
9892         test_mkdir -i0 -c1 $DIR/$tdir
9893         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9894                 skip_env "no early lock cancel on server"
9895
9896         lru_resize_disable mdc
9897         lru_resize_disable osc
9898         touch $DIR/$tdir
9899         cancel_lru_locks mdc
9900         stat $DIR/$tdir > /dev/null
9901         can1=$(do_facet mds1 \
9902                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9903                awk '/ldlm_cancel/ {print $2}')
9904         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9905                awk '/ldlm_bl_callback/ {print $2}')
9906         chmod a+x $DIR/$tdir
9907         can2=$(do_facet mds1 \
9908                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9909                awk '/ldlm_cancel/ {print $2}')
9910         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9911                awk '/ldlm_bl_callback/ {print $2}')
9912         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9913         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9914         lru_resize_enable mdc
9915         lru_resize_enable osc
9916 }
9917 run_test 120d "Early Lock Cancel: setattr test"
9918
9919 test_120e() {
9920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9921         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9922                 skip_env "no early lock cancel on server"
9923         remote_mds_nodsh && skip "remote MDS with nodsh"
9924
9925         local dlmtrace_set=false
9926
9927         test_mkdir -i0 -c1 $DIR/$tdir
9928         lru_resize_disable mdc
9929         lru_resize_disable osc
9930         ! $LCTL get_param debug | grep -q dlmtrace &&
9931                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
9932         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
9933         cancel_lru_locks mdc
9934         cancel_lru_locks osc
9935         dd if=$DIR/$tdir/f1 of=/dev/null
9936         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
9937         # XXX client can not do early lock cancel of OST lock
9938         # during unlink (LU-4206), so cancel osc lock now.
9939         sleep 2
9940         cancel_lru_locks osc
9941         can1=$(do_facet mds1 \
9942                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9943                awk '/ldlm_cancel/ {print $2}')
9944         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9945                awk '/ldlm_bl_callback/ {print $2}')
9946         unlink $DIR/$tdir/f1
9947         sleep 5
9948         can2=$(do_facet mds1 \
9949                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9950                awk '/ldlm_cancel/ {print $2}')
9951         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9952                awk '/ldlm_bl_callback/ {print $2}')
9953         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
9954                 $LCTL dk $TMP/cancel.debug.txt
9955         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
9956                 $LCTL dk $TMP/blocking.debug.txt
9957         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
9958         lru_resize_enable mdc
9959         lru_resize_enable osc
9960 }
9961 run_test 120e "Early Lock Cancel: unlink test"
9962
9963 test_120f() {
9964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9965         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9966                 skip_env "no early lock cancel on server"
9967         remote_mds_nodsh && skip "remote MDS with nodsh"
9968
9969         test_mkdir -i0 -c1 $DIR/$tdir
9970         lru_resize_disable mdc
9971         lru_resize_disable osc
9972         test_mkdir -i0 -c1 $DIR/$tdir/d1
9973         test_mkdir -i0 -c1 $DIR/$tdir/d2
9974         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
9975         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
9976         cancel_lru_locks mdc
9977         cancel_lru_locks osc
9978         dd if=$DIR/$tdir/d1/f1 of=/dev/null
9979         dd if=$DIR/$tdir/d2/f2 of=/dev/null
9980         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
9981         # XXX client can not do early lock cancel of OST lock
9982         # during rename (LU-4206), so cancel osc lock now.
9983         sleep 2
9984         cancel_lru_locks osc
9985         can1=$(do_facet mds1 \
9986                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9987                awk '/ldlm_cancel/ {print $2}')
9988         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9989                awk '/ldlm_bl_callback/ {print $2}')
9990         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
9991         sleep 5
9992         can2=$(do_facet mds1 \
9993                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9994                awk '/ldlm_cancel/ {print $2}')
9995         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9996                awk '/ldlm_bl_callback/ {print $2}')
9997         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9998         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9999         lru_resize_enable mdc
10000         lru_resize_enable osc
10001 }
10002 run_test 120f "Early Lock Cancel: rename test"
10003
10004 test_120g() {
10005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10006         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10007                 skip_env "no early lock cancel on server"
10008         remote_mds_nodsh && skip "remote MDS with nodsh"
10009
10010         lru_resize_disable mdc
10011         lru_resize_disable osc
10012         count=10000
10013         echo create $count files
10014         test_mkdir $DIR/$tdir
10015         cancel_lru_locks mdc
10016         cancel_lru_locks osc
10017         t0=$(date +%s)
10018
10019         can0=$(do_facet $SINGLEMDS \
10020                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10021                awk '/ldlm_cancel/ {print $2}')
10022         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10023                awk '/ldlm_bl_callback/ {print $2}')
10024         createmany -o $DIR/$tdir/f $count
10025         sync
10026         can1=$(do_facet $SINGLEMDS \
10027                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10028                awk '/ldlm_cancel/ {print $2}')
10029         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10030                awk '/ldlm_bl_callback/ {print $2}')
10031         t1=$(date +%s)
10032         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
10033         echo rm $count files
10034         rm -r $DIR/$tdir
10035         sync
10036         can2=$(do_facet $SINGLEMDS \
10037                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10038                awk '/ldlm_cancel/ {print $2}')
10039         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10040                awk '/ldlm_bl_callback/ {print $2}')
10041         t2=$(date +%s)
10042         echo total: $count removes in $((t2-t1))
10043         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
10044         sleep 2
10045         # wait for commitment of removal
10046         lru_resize_enable mdc
10047         lru_resize_enable osc
10048 }
10049 run_test 120g "Early Lock Cancel: performance test"
10050
10051 test_121() { #bug #10589
10052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10053
10054         rm -rf $DIR/$tfile
10055         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
10056 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
10057         lctl set_param fail_loc=0x310
10058         cancel_lru_locks osc > /dev/null
10059         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
10060         lctl set_param fail_loc=0
10061         [[ $reads -eq $writes ]] ||
10062                 error "read $reads blocks, must be $writes blocks"
10063 }
10064 run_test 121 "read cancel race ========="
10065
10066 test_123a() { # was test 123, statahead(bug 11401)
10067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10068
10069         SLOWOK=0
10070         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
10071                 log "testing UP system. Performance may be lower than expected."
10072                 SLOWOK=1
10073         fi
10074
10075         rm -rf $DIR/$tdir
10076         test_mkdir $DIR/$tdir
10077         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
10078         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
10079         MULT=10
10080         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
10081                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
10082
10083                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10084                 lctl set_param -n llite.*.statahead_max 0
10085                 lctl get_param llite.*.statahead_max
10086                 cancel_lru_locks mdc
10087                 cancel_lru_locks osc
10088                 stime=`date +%s`
10089                 time ls -l $DIR/$tdir | wc -l
10090                 etime=`date +%s`
10091                 delta=$((etime - stime))
10092                 log "ls $i files without statahead: $delta sec"
10093                 lctl set_param llite.*.statahead_max=$max
10094
10095                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10096                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
10097                 cancel_lru_locks mdc
10098                 cancel_lru_locks osc
10099                 stime=`date +%s`
10100                 time ls -l $DIR/$tdir | wc -l
10101                 etime=`date +%s`
10102                 delta_sa=$((etime - stime))
10103                 log "ls $i files with statahead: $delta_sa sec"
10104                 lctl get_param -n llite.*.statahead_stats
10105                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10106
10107                 [[ $swrong -lt $ewrong ]] &&
10108                         log "statahead was stopped, maybe too many locks held!"
10109                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
10110
10111                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10112                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10113                     lctl set_param -n llite.*.statahead_max 0
10114                     lctl get_param llite.*.statahead_max
10115                     cancel_lru_locks mdc
10116                     cancel_lru_locks osc
10117                     stime=`date +%s`
10118                     time ls -l $DIR/$tdir | wc -l
10119                     etime=`date +%s`
10120                     delta=$((etime - stime))
10121                     log "ls $i files again without statahead: $delta sec"
10122                     lctl set_param llite.*.statahead_max=$max
10123                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10124                         if [  $SLOWOK -eq 0 ]; then
10125                                 error "ls $i files is slower with statahead!"
10126                         else
10127                                 log "ls $i files is slower with statahead!"
10128                         fi
10129                         break
10130                     fi
10131                 fi
10132
10133                 [ $delta -gt 20 ] && break
10134                 [ $delta -gt 8 ] && MULT=$((50 / delta))
10135                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
10136         done
10137         log "ls done"
10138
10139         stime=`date +%s`
10140         rm -r $DIR/$tdir
10141         sync
10142         etime=`date +%s`
10143         delta=$((etime - stime))
10144         log "rm -r $DIR/$tdir/: $delta seconds"
10145         log "rm done"
10146         lctl get_param -n llite.*.statahead_stats
10147 }
10148 run_test 123a "verify statahead work"
10149
10150 test_123b () { # statahead(bug 15027)
10151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10152
10153         test_mkdir $DIR/$tdir
10154         createmany -o $DIR/$tdir/$tfile-%d 1000
10155
10156         cancel_lru_locks mdc
10157         cancel_lru_locks osc
10158
10159 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
10160         lctl set_param fail_loc=0x80000803
10161         ls -lR $DIR/$tdir > /dev/null
10162         log "ls done"
10163         lctl set_param fail_loc=0x0
10164         lctl get_param -n llite.*.statahead_stats
10165         rm -r $DIR/$tdir
10166         sync
10167
10168 }
10169 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
10170
10171 test_124a() {
10172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10173         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10174                 skip_env "no lru resize on server"
10175
10176         local NR=2000
10177
10178         test_mkdir $DIR/$tdir
10179
10180         log "create $NR files at $DIR/$tdir"
10181         createmany -o $DIR/$tdir/f $NR ||
10182                 error "failed to create $NR files in $DIR/$tdir"
10183
10184         cancel_lru_locks mdc
10185         ls -l $DIR/$tdir > /dev/null
10186
10187         local NSDIR=""
10188         local LRU_SIZE=0
10189         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
10190                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
10191                 LRU_SIZE=$($LCTL get_param -n $PARAM)
10192                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
10193                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
10194                         log "NSDIR=$NSDIR"
10195                         log "NS=$(basename $NSDIR)"
10196                         break
10197                 fi
10198         done
10199
10200         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
10201                 skip "Not enough cached locks created!"
10202         fi
10203         log "LRU=$LRU_SIZE"
10204
10205         local SLEEP=30
10206
10207         # We know that lru resize allows one client to hold $LIMIT locks
10208         # for 10h. After that locks begin to be killed by client.
10209         local MAX_HRS=10
10210         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
10211         log "LIMIT=$LIMIT"
10212         if [ $LIMIT -lt $LRU_SIZE ]; then
10213                 skip "Limit is too small $LIMIT"
10214         fi
10215
10216         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
10217         # killing locks. Some time was spent for creating locks. This means
10218         # that up to the moment of sleep finish we must have killed some of
10219         # them (10-100 locks). This depends on how fast ther were created.
10220         # Many of them were touched in almost the same moment and thus will
10221         # be killed in groups.
10222         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
10223
10224         # Use $LRU_SIZE_B here to take into account real number of locks
10225         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
10226         local LRU_SIZE_B=$LRU_SIZE
10227         log "LVF=$LVF"
10228         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
10229         log "OLD_LVF=$OLD_LVF"
10230         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
10231
10232         # Let's make sure that we really have some margin. Client checks
10233         # cached locks every 10 sec.
10234         SLEEP=$((SLEEP+20))
10235         log "Sleep ${SLEEP} sec"
10236         local SEC=0
10237         while ((SEC<$SLEEP)); do
10238                 echo -n "..."
10239                 sleep 5
10240                 SEC=$((SEC+5))
10241                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
10242                 echo -n "$LRU_SIZE"
10243         done
10244         echo ""
10245         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
10246         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
10247
10248         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
10249                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
10250                 unlinkmany $DIR/$tdir/f $NR
10251                 return
10252         }
10253
10254         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
10255         log "unlink $NR files at $DIR/$tdir"
10256         unlinkmany $DIR/$tdir/f $NR
10257 }
10258 run_test 124a "lru resize ======================================="
10259
10260 get_max_pool_limit()
10261 {
10262         local limit=$($LCTL get_param \
10263                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
10264         local max=0
10265         for l in $limit; do
10266                 if [[ $l -gt $max ]]; then
10267                         max=$l
10268                 fi
10269         done
10270         echo $max
10271 }
10272
10273 test_124b() {
10274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10275         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10276                 skip_env "no lru resize on server"
10277
10278         LIMIT=$(get_max_pool_limit)
10279
10280         NR=$(($(default_lru_size)*20))
10281         if [[ $NR -gt $LIMIT ]]; then
10282                 log "Limit lock number by $LIMIT locks"
10283                 NR=$LIMIT
10284         fi
10285
10286         IFree=$(mdsrate_inodes_available)
10287         if [ $IFree -lt $NR ]; then
10288                 log "Limit lock number by $IFree inodes"
10289                 NR=$IFree
10290         fi
10291
10292         lru_resize_disable mdc
10293         test_mkdir -p $DIR/$tdir/disable_lru_resize
10294
10295         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
10296         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
10297         cancel_lru_locks mdc
10298         stime=`date +%s`
10299         PID=""
10300         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10301         PID="$PID $!"
10302         sleep 2
10303         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10304         PID="$PID $!"
10305         sleep 2
10306         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10307         PID="$PID $!"
10308         wait $PID
10309         etime=`date +%s`
10310         nolruresize_delta=$((etime-stime))
10311         log "ls -la time: $nolruresize_delta seconds"
10312         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10313         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
10314
10315         lru_resize_enable mdc
10316         test_mkdir -p $DIR/$tdir/enable_lru_resize
10317
10318         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
10319         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
10320         cancel_lru_locks mdc
10321         stime=`date +%s`
10322         PID=""
10323         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10324         PID="$PID $!"
10325         sleep 2
10326         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10327         PID="$PID $!"
10328         sleep 2
10329         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10330         PID="$PID $!"
10331         wait $PID
10332         etime=`date +%s`
10333         lruresize_delta=$((etime-stime))
10334         log "ls -la time: $lruresize_delta seconds"
10335         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10336
10337         if [ $lruresize_delta -gt $nolruresize_delta ]; then
10338                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
10339         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
10340                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
10341         else
10342                 log "lru resize performs the same with no lru resize"
10343         fi
10344         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
10345 }
10346 run_test 124b "lru resize (performance test) ======================="
10347
10348 test_124c() {
10349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10350         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10351                 skip_env "no lru resize on server"
10352
10353         # cache ununsed locks on client
10354         local nr=100
10355         cancel_lru_locks mdc
10356         test_mkdir $DIR/$tdir
10357         createmany -o $DIR/$tdir/f $nr ||
10358                 error "failed to create $nr files in $DIR/$tdir"
10359         ls -l $DIR/$tdir > /dev/null
10360
10361         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
10362         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
10363         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
10364         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
10365         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
10366
10367         # set lru_max_age to 1 sec
10368         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
10369         echo "sleep $((recalc_p * 2)) seconds..."
10370         sleep $((recalc_p * 2))
10371
10372         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
10373         # restore lru_max_age
10374         $LCTL set_param -n $nsdir.lru_max_age $max_age
10375         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
10376         unlinkmany $DIR/$tdir/f $nr
10377 }
10378 run_test 124c "LRUR cancel very aged locks"
10379
10380 test_125() { # 13358
10381         $LCTL get_param -n llite.*.client_type | grep -q local ||
10382                 skip "must run as local client"
10383         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
10384                 skip_env "must have acl enabled"
10385         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
10386
10387         test_mkdir $DIR/$tdir
10388         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
10389         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
10390         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
10391 }
10392 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
10393
10394 test_126() { # bug 12829/13455
10395         $GSS && skip_env "must run as gss disabled"
10396         $LCTL get_param -n llite.*.client_type | grep -q local ||
10397                 skip "must run as local client"
10398         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
10399
10400         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
10401         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
10402         rm -f $DIR/$tfile
10403         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
10404 }
10405 run_test 126 "check that the fsgid provided by the client is taken into account"
10406
10407 test_127a() { # bug 15521
10408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10409
10410         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
10411         $LCTL set_param osc.*.stats=0
10412         FSIZE=$((2048 * 1024))
10413         dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
10414         cancel_lru_locks osc
10415         dd if=$DIR/$tfile of=/dev/null bs=$FSIZE
10416
10417         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/${tfile}.tmp
10418         while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
10419                 echo "got $COUNT $NAME"
10420                 [ ! $MIN ] && error "Missing min value for $NAME proc entry"
10421                 eval $NAME=$COUNT || error "Wrong proc format"
10422
10423                 case $NAME in
10424                         read_bytes|write_bytes)
10425                         [ $MIN -lt 4096 ] && error "min is too small: $MIN"
10426                         [ $MIN -gt $FSIZE ] && error "min is too big: $MIN"
10427                         [ $MAX -lt 4096 ] && error "max is too small: $MAX"
10428                         [ $MAX -gt $FSIZE ] && error "max is too big: $MAX"
10429                         [ $SUM -ne $FSIZE ] && error "sum is wrong: $SUM"
10430                         [ $SUMSQ -lt $(((FSIZE /4096) * (4096 * 4096))) ] &&
10431                                 error "sumsquare is too small: $SUMSQ"
10432                         [ $SUMSQ -gt $((FSIZE * FSIZE)) ] &&
10433                                 error "sumsquare is too big: $SUMSQ"
10434                         ;;
10435                         *) ;;
10436                 esac
10437         done < $DIR/${tfile}.tmp
10438
10439         #check that we actually got some stats
10440         [ "$read_bytes" ] || error "Missing read_bytes stats"
10441         [ "$write_bytes" ] || error "Missing write_bytes stats"
10442         [ "$read_bytes" != 0 ] || error "no read done"
10443         [ "$write_bytes" != 0 ] || error "no write done"
10444 }
10445 run_test 127a "verify the client stats are sane"
10446
10447 test_127b() { # bug LU-333
10448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10449         local name count samp unit min max sum sumsq
10450
10451         $LCTL set_param llite.*.stats=0
10452
10453         # perform 2 reads and writes so MAX is different from SUM.
10454         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10455         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10456         cancel_lru_locks osc
10457         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10458         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10459
10460         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
10461         while read name count samp unit min max sum sumsq; do
10462                 echo "got $count $name"
10463                 eval $name=$count || error "Wrong proc format"
10464
10465                 case $name in
10466                 read_bytes)
10467                         [ $count -ne 2 ] && error "count is not 2: $count"
10468                         [ $min -ne $PAGE_SIZE ] &&
10469                                 error "min is not $PAGE_SIZE: $min"
10470                         [ $max -ne $PAGE_SIZE ] &&
10471                                 error "max is incorrect: $max"
10472                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10473                                 error "sum is wrong: $sum"
10474                         ;;
10475                 write_bytes)
10476                         [ $count -ne 2 ] && error "count is not 2: $count"
10477                         [ $min -ne $PAGE_SIZE ] &&
10478                                 error "min is not $PAGE_SIZE: $min"
10479                         [ $max -ne $PAGE_SIZE ] &&
10480                                 error "max is incorrect: $max"
10481                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10482                                 error "sum is wrong: $sum"
10483                         ;;
10484                 *) ;;
10485                 esac
10486         done < $TMP/$tfile.tmp
10487
10488         #check that we actually got some stats
10489         [ "$read_bytes" ] || error "Missing read_bytes stats"
10490         [ "$write_bytes" ] || error "Missing write_bytes stats"
10491         [ "$read_bytes" != 0 ] || error "no read done"
10492         [ "$write_bytes" != 0 ] || error "no write done"
10493
10494         rm -f $TMP/${tfile}.tmp
10495 }
10496 run_test 127b "verify the llite client stats are sane"
10497
10498 test_128() { # bug 15212
10499         touch $DIR/$tfile
10500         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
10501                 find $DIR/$tfile
10502                 find $DIR/$tfile
10503         EOF
10504
10505         result=$(grep error $TMP/$tfile.log)
10506         rm -f $DIR/$tfile $TMP/$tfile.log
10507         [ -z "$result" ] ||
10508                 error "consecutive find's under interactive lfs failed"
10509 }
10510 run_test 128 "interactive lfs for 2 consecutive find's"
10511
10512 set_dir_limits () {
10513         local mntdev
10514         local canondev
10515         local node
10516
10517         local ldproc=/proc/fs/ldiskfs
10518         local facets=$(get_facets MDS)
10519
10520         for facet in ${facets//,/ }; do
10521                 canondev=$(ldiskfs_canon \
10522                            *.$(convert_facet2label $facet).mntdev $facet)
10523                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
10524                         ldproc=/sys/fs/ldiskfs
10525                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
10526                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
10527         done
10528 }
10529
10530 check_mds_dmesg() {
10531         local facets=$(get_facets MDS)
10532         for facet in ${facets//,/ }; do
10533                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
10534         done
10535         return 1
10536 }
10537
10538 test_129() {
10539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10540         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
10541                 skip "Need MDS version with at least 2.5.56"
10542         if [ "$mds1_FSTYPE" != ldiskfs ]; then
10543                 skip_env "ldiskfs only test"
10544         fi
10545         remote_mds_nodsh && skip "remote MDS with nodsh"
10546
10547         local ENOSPC=28
10548         local EFBIG=27
10549         local has_warning=false
10550
10551         rm -rf $DIR/$tdir
10552         mkdir -p $DIR/$tdir
10553
10554         # block size of mds1
10555         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
10556         set_dir_limits $maxsize $maxsize
10557         local dirsize=$(stat -c%s "$DIR/$tdir")
10558         local nfiles=0
10559         while [[ $dirsize -le $maxsize ]]; do
10560                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
10561                 rc=$?
10562                 if ! $has_warning; then
10563                         check_mds_dmesg '"is approaching"' && has_warning=true
10564                 fi
10565                 # check two errors:
10566                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
10567                 # EFBIG for previous versions included in ldiskfs series
10568                 if [ $rc -eq $EFBIG ] || [ $rc -eq $ENOSPC ]; then
10569                         set_dir_limits 0 0
10570                         echo "return code $rc received as expected"
10571
10572                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
10573                                 error_exit "create failed w/o dir size limit"
10574
10575                         check_mds_dmesg '"has reached"' ||
10576                                 error_exit "reached message should be output"
10577
10578                         [ $has_warning = "false" ] &&
10579                                 error_exit "warning message should be output"
10580
10581                         dirsize=$(stat -c%s "$DIR/$tdir")
10582
10583                         [[ $dirsize -ge $maxsize ]] && return 0
10584                         error_exit "current dir size $dirsize, " \
10585                                    "previous limit $maxsize"
10586                 elif [ $rc -ne 0 ]; then
10587                         set_dir_limits 0 0
10588                         error_exit "return $rc received instead of expected " \
10589                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
10590                 fi
10591                 nfiles=$((nfiles + 1))
10592                 dirsize=$(stat -c%s "$DIR/$tdir")
10593         done
10594
10595         set_dir_limits 0 0
10596         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
10597 }
10598 run_test 129 "test directory size limit ========================"
10599
10600 OLDIFS="$IFS"
10601 cleanup_130() {
10602         trap 0
10603         IFS="$OLDIFS"
10604 }
10605
10606 test_130a() {
10607         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10608         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10609
10610         trap cleanup_130 EXIT RETURN
10611
10612         local fm_file=$DIR/$tfile
10613         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
10614         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
10615                 error "dd failed for $fm_file"
10616
10617         # LU-1795: test filefrag/FIEMAP once, even if unsupported
10618         filefrag -ves $fm_file
10619         RC=$?
10620         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10621                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10622         [ $RC != 0 ] && error "filefrag $fm_file failed"
10623
10624         filefrag_op=$(filefrag -ve -k $fm_file |
10625                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10626         lun=$($LFS getstripe -i $fm_file)
10627
10628         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
10629         IFS=$'\n'
10630         tot_len=0
10631         for line in $filefrag_op
10632         do
10633                 frag_lun=`echo $line | cut -d: -f5`
10634                 ext_len=`echo $line | cut -d: -f4`
10635                 if (( $frag_lun != $lun )); then
10636                         cleanup_130
10637                         error "FIEMAP on 1-stripe file($fm_file) failed"
10638                         return
10639                 fi
10640                 (( tot_len += ext_len ))
10641         done
10642
10643         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
10644                 cleanup_130
10645                 error "FIEMAP on 1-stripe file($fm_file) failed;"
10646                 return
10647         fi
10648
10649         cleanup_130
10650
10651         echo "FIEMAP on single striped file succeeded"
10652 }
10653 run_test 130a "FIEMAP (1-stripe file)"
10654
10655 test_130b() {
10656         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
10657
10658         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10659         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10660
10661         trap cleanup_130 EXIT RETURN
10662
10663         local fm_file=$DIR/$tfile
10664         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
10665                         error "setstripe on $fm_file"
10666         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10667                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10668
10669         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
10670                 error "dd failed on $fm_file"
10671
10672         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10673         filefrag_op=$(filefrag -ve -k $fm_file |
10674                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10675
10676         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10677                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10678
10679         IFS=$'\n'
10680         tot_len=0
10681         num_luns=1
10682         for line in $filefrag_op
10683         do
10684                 frag_lun=$(echo $line | cut -d: -f5 |
10685                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10686                 ext_len=$(echo $line | cut -d: -f4)
10687                 if (( $frag_lun != $last_lun )); then
10688                         if (( tot_len != 1024 )); then
10689                                 cleanup_130
10690                                 error "FIEMAP on $fm_file failed; returned " \
10691                                 "len $tot_len for OST $last_lun instead of 1024"
10692                                 return
10693                         else
10694                                 (( num_luns += 1 ))
10695                                 tot_len=0
10696                         fi
10697                 fi
10698                 (( tot_len += ext_len ))
10699                 last_lun=$frag_lun
10700         done
10701         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
10702                 cleanup_130
10703                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10704                         "luns or wrong len for OST $last_lun"
10705                 return
10706         fi
10707
10708         cleanup_130
10709
10710         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
10711 }
10712 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
10713
10714 test_130c() {
10715         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10716
10717         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10718         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10719
10720         trap cleanup_130 EXIT RETURN
10721
10722         local fm_file=$DIR/$tfile
10723         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
10724         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10725                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10726
10727         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
10728                         error "dd failed on $fm_file"
10729
10730         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10731         filefrag_op=$(filefrag -ve -k $fm_file |
10732                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10733
10734         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10735                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10736
10737         IFS=$'\n'
10738         tot_len=0
10739         num_luns=1
10740         for line in $filefrag_op
10741         do
10742                 frag_lun=$(echo $line | cut -d: -f5 |
10743                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10744                 ext_len=$(echo $line | cut -d: -f4)
10745                 if (( $frag_lun != $last_lun )); then
10746                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
10747                         if (( logical != 512 )); then
10748                                 cleanup_130
10749                                 error "FIEMAP on $fm_file failed; returned " \
10750                                 "logical start for lun $logical instead of 512"
10751                                 return
10752                         fi
10753                         if (( tot_len != 512 )); then
10754                                 cleanup_130
10755                                 error "FIEMAP on $fm_file failed; returned " \
10756                                 "len $tot_len for OST $last_lun instead of 1024"
10757                                 return
10758                         else
10759                                 (( num_luns += 1 ))
10760                                 tot_len=0
10761                         fi
10762                 fi
10763                 (( tot_len += ext_len ))
10764                 last_lun=$frag_lun
10765         done
10766         if (( num_luns != 2 || tot_len != 512 )); then
10767                 cleanup_130
10768                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10769                         "luns or wrong len for OST $last_lun"
10770                 return
10771         fi
10772
10773         cleanup_130
10774
10775         echo "FIEMAP on 2-stripe file with hole succeeded"
10776 }
10777 run_test 130c "FIEMAP (2-stripe file with hole)"
10778
10779 test_130d() {
10780         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
10781
10782         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10783         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10784
10785         trap cleanup_130 EXIT RETURN
10786
10787         local fm_file=$DIR/$tfile
10788         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
10789                         error "setstripe on $fm_file"
10790         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10791                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10792
10793         local actual_stripe_count=$($LFS getstripe -c $fm_file)
10794         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
10795                 error "dd failed on $fm_file"
10796
10797         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10798         filefrag_op=$(filefrag -ve -k $fm_file |
10799                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10800
10801         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10802                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10803
10804         IFS=$'\n'
10805         tot_len=0
10806         num_luns=1
10807         for line in $filefrag_op
10808         do
10809                 frag_lun=$(echo $line | cut -d: -f5 |
10810                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10811                 ext_len=$(echo $line | cut -d: -f4)
10812                 if (( $frag_lun != $last_lun )); then
10813                         if (( tot_len != 1024 )); then
10814                                 cleanup_130
10815                                 error "FIEMAP on $fm_file failed; returned " \
10816                                 "len $tot_len for OST $last_lun instead of 1024"
10817                                 return
10818                         else
10819                                 (( num_luns += 1 ))
10820                                 tot_len=0
10821                         fi
10822                 fi
10823                 (( tot_len += ext_len ))
10824                 last_lun=$frag_lun
10825         done
10826         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
10827                 cleanup_130
10828                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10829                         "luns or wrong len for OST $last_lun"
10830                 return
10831         fi
10832
10833         cleanup_130
10834
10835         echo "FIEMAP on N-stripe file succeeded"
10836 }
10837 run_test 130d "FIEMAP (N-stripe file)"
10838
10839 test_130e() {
10840         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10841
10842         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10843         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10844
10845         trap cleanup_130 EXIT RETURN
10846
10847         local fm_file=$DIR/$tfile
10848         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
10849         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10850                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10851
10852         NUM_BLKS=512
10853         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
10854         for ((i = 0; i < $NUM_BLKS; i++))
10855         do
10856                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
10857         done
10858
10859         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10860         filefrag_op=$(filefrag -ve -k $fm_file |
10861                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10862
10863         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10864                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10865
10866         IFS=$'\n'
10867         tot_len=0
10868         num_luns=1
10869         for line in $filefrag_op
10870         do
10871                 frag_lun=$(echo $line | cut -d: -f5 |
10872                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10873                 ext_len=$(echo $line | cut -d: -f4)
10874                 if (( $frag_lun != $last_lun )); then
10875                         if (( tot_len != $EXPECTED_LEN )); then
10876                                 cleanup_130
10877                                 error "FIEMAP on $fm_file failed; returned " \
10878                                 "len $tot_len for OST $last_lun instead " \
10879                                 "of $EXPECTED_LEN"
10880                                 return
10881                         else
10882                                 (( num_luns += 1 ))
10883                                 tot_len=0
10884                         fi
10885                 fi
10886                 (( tot_len += ext_len ))
10887                 last_lun=$frag_lun
10888         done
10889         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
10890                 cleanup_130
10891                 error "FIEMAP on $fm_file failed; returned wrong number " \
10892                         "of luns or wrong len for OST $last_lun"
10893                 return
10894         fi
10895
10896         cleanup_130
10897
10898         echo "FIEMAP with continuation calls succeeded"
10899 }
10900 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
10901
10902 test_130f() {
10903         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10904         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10905
10906         local fm_file=$DIR/$tfile
10907         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
10908                 error "multiop create with lov_delay_create on $fm_file"
10909
10910         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10911         filefrag_extents=$(filefrag -vek $fm_file |
10912                            awk '/extents? found/ { print $2 }')
10913         if [[ "$filefrag_extents" != "0" ]]; then
10914                 error "FIEMAP on $fm_file failed; " \
10915                       "returned $filefrag_extents expected 0"
10916         fi
10917
10918         rm -f $fm_file
10919 }
10920 run_test 130f "FIEMAP (unstriped file)"
10921
10922 # Test for writev/readv
10923 test_131a() {
10924         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
10925                 error "writev test failed"
10926         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
10927                 error "readv failed"
10928         rm -f $DIR/$tfile
10929 }
10930 run_test 131a "test iov's crossing stripe boundary for writev/readv"
10931
10932 test_131b() {
10933         local fsize=$((524288 + 1048576 + 1572864))
10934         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
10935                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
10936                         error "append writev test failed"
10937
10938         ((fsize += 1572864 + 1048576))
10939         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
10940                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
10941                         error "append writev test failed"
10942         rm -f $DIR/$tfile
10943 }
10944 run_test 131b "test append writev"
10945
10946 test_131c() {
10947         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
10948         error "NOT PASS"
10949 }
10950 run_test 131c "test read/write on file w/o objects"
10951
10952 test_131d() {
10953         rwv -f $DIR/$tfile -w -n 1 1572864
10954         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
10955         if [ "$NOB" != 1572864 ]; then
10956                 error "Short read filed: read $NOB bytes instead of 1572864"
10957         fi
10958         rm -f $DIR/$tfile
10959 }
10960 run_test 131d "test short read"
10961
10962 test_131e() {
10963         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
10964         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
10965         error "read hitting hole failed"
10966         rm -f $DIR/$tfile
10967 }
10968 run_test 131e "test read hitting hole"
10969
10970 check_stats() {
10971         local facet=$1
10972         local op=$2
10973         local want=${3:-0}
10974         local res
10975
10976         case $facet in
10977         mds*) res=$(do_facet $facet \
10978                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
10979                  ;;
10980         ost*) res=$(do_facet $facet \
10981                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
10982                  ;;
10983         *) error "Wrong facet '$facet'" ;;
10984         esac
10985         [ "$res" ] || error "The counter for $op on $facet was not incremented"
10986         # if the argument $3 is zero, it means any stat increment is ok.
10987         if [[ $want -gt 0 ]]; then
10988                 local count=$(echo $res | awk '{ print $2 }')
10989                 [[ $count -ne $want ]] &&
10990                         error "The $op counter on $facet is $count, not $want"
10991         fi
10992 }
10993
10994 test_133a() {
10995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10996         remote_ost_nodsh && skip "remote OST with nodsh"
10997         remote_mds_nodsh && skip "remote MDS with nodsh"
10998         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
10999                 skip_env "MDS doesn't support rename stats"
11000
11001         local testdir=$DIR/${tdir}/stats_testdir
11002
11003         mkdir -p $DIR/${tdir}
11004
11005         # clear stats.
11006         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11007         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11008
11009         # verify mdt stats first.
11010         mkdir ${testdir} || error "mkdir failed"
11011         check_stats $SINGLEMDS "mkdir" 1
11012         touch ${testdir}/${tfile} || error "touch failed"
11013         check_stats $SINGLEMDS "open" 1
11014         check_stats $SINGLEMDS "close" 1
11015         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
11016                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
11017                 check_stats $SINGLEMDS "mknod" 2
11018         }
11019         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
11020         check_stats $SINGLEMDS "unlink" 1
11021         rm -f ${testdir}/${tfile} || error "file remove failed"
11022         check_stats $SINGLEMDS "unlink" 2
11023
11024         # remove working dir and check mdt stats again.
11025         rmdir ${testdir} || error "rmdir failed"
11026         check_stats $SINGLEMDS "rmdir" 1
11027
11028         local testdir1=$DIR/${tdir}/stats_testdir1
11029         mkdir -p ${testdir}
11030         mkdir -p ${testdir1}
11031         touch ${testdir1}/test1
11032         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
11033         check_stats $SINGLEMDS "crossdir_rename" 1
11034
11035         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
11036         check_stats $SINGLEMDS "samedir_rename" 1
11037
11038         rm -rf $DIR/${tdir}
11039 }
11040 run_test 133a "Verifying MDT stats ========================================"
11041
11042 test_133b() {
11043         local res
11044
11045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11046         remote_ost_nodsh && skip "remote OST with nodsh"
11047         remote_mds_nodsh && skip "remote MDS with nodsh"
11048
11049         local testdir=$DIR/${tdir}/stats_testdir
11050
11051         mkdir -p ${testdir} || error "mkdir failed"
11052         touch ${testdir}/${tfile} || error "touch failed"
11053         cancel_lru_locks mdc
11054
11055         # clear stats.
11056         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11057         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11058
11059         # extra mdt stats verification.
11060         chmod 444 ${testdir}/${tfile} || error "chmod failed"
11061         check_stats $SINGLEMDS "setattr" 1
11062         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11063         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
11064         then            # LU-1740
11065                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
11066                 check_stats $SINGLEMDS "getattr" 1
11067         fi
11068         rm -rf $DIR/${tdir}
11069
11070         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
11071         # so the check below is not reliable
11072         [ $MDSCOUNT -eq 1 ] || return 0
11073
11074         # Sleep to avoid a cached response.
11075         #define OBD_STATFS_CACHE_SECONDS 1
11076         sleep 2
11077         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11078         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11079         $LFS df || error "lfs failed"
11080         check_stats $SINGLEMDS "statfs" 1
11081
11082         # check aggregated statfs (LU-10018)
11083         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
11084                 return 0
11085         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
11086                 return 0
11087         sleep 2
11088         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11089         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11090         df $DIR
11091         check_stats $SINGLEMDS "statfs" 1
11092
11093         # We want to check that the client didn't send OST_STATFS to
11094         # ost1 but the MDT also uses OST_STATFS for precreate. So some
11095         # extra care is needed here.
11096         if remote_mds; then
11097                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
11098                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
11099
11100                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
11101                 [ "$res" ] && error "OST got STATFS"
11102         fi
11103
11104         return 0
11105 }
11106 run_test 133b "Verifying extra MDT stats =================================="
11107
11108 test_133c() {
11109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11110         remote_ost_nodsh && skip "remote OST with nodsh"
11111         remote_mds_nodsh && skip "remote MDS with nodsh"
11112
11113         local testdir=$DIR/$tdir/stats_testdir
11114
11115         test_mkdir -p $testdir
11116
11117         # verify obdfilter stats.
11118         $LFS setstripe -c 1 -i 0 $testdir/$tfile
11119         sync
11120         cancel_lru_locks osc
11121         wait_delete_completed
11122
11123         # clear stats.
11124         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11125         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11126
11127         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
11128                 error "dd failed"
11129         sync
11130         cancel_lru_locks osc
11131         check_stats ost1 "write" 1
11132
11133         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
11134         check_stats ost1 "read" 1
11135
11136         > $testdir/$tfile || error "truncate failed"
11137         check_stats ost1 "punch" 1
11138
11139         rm -f $testdir/$tfile || error "file remove failed"
11140         wait_delete_completed
11141         check_stats ost1 "destroy" 1
11142
11143         rm -rf $DIR/$tdir
11144 }
11145 run_test 133c "Verifying OST stats ========================================"
11146
11147 order_2() {
11148         local value=$1
11149         local orig=$value
11150         local order=1
11151
11152         while [ $value -ge 2 ]; do
11153                 order=$((order*2))
11154                 value=$((value/2))
11155         done
11156
11157         if [ $orig -gt $order ]; then
11158                 order=$((order*2))
11159         fi
11160         echo $order
11161 }
11162
11163 size_in_KMGT() {
11164     local value=$1
11165     local size=('K' 'M' 'G' 'T');
11166     local i=0
11167     local size_string=$value
11168
11169     while [ $value -ge 1024 ]; do
11170         if [ $i -gt 3 ]; then
11171             #T is the biggest unit we get here, if that is bigger,
11172             #just return XXXT
11173             size_string=${value}T
11174             break
11175         fi
11176         value=$((value >> 10))
11177         if [ $value -lt 1024 ]; then
11178             size_string=${value}${size[$i]}
11179             break
11180         fi
11181         i=$((i + 1))
11182     done
11183
11184     echo $size_string
11185 }
11186
11187 get_rename_size() {
11188         local size=$1
11189         local context=${2:-.}
11190         local sample=$(do_facet $SINGLEMDS $LCTL \
11191                 get_param mdt.$FSNAME-MDT0000.rename_stats |
11192                 grep -A1 $context |
11193                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
11194         echo $sample
11195 }
11196
11197 test_133d() {
11198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11199         remote_ost_nodsh && skip "remote OST with nodsh"
11200         remote_mds_nodsh && skip "remote MDS with nodsh"
11201         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11202                 skip_env "MDS doesn't support rename stats"
11203
11204         local testdir1=$DIR/${tdir}/stats_testdir1
11205         local testdir2=$DIR/${tdir}/stats_testdir2
11206         mkdir -p $DIR/${tdir}
11207
11208         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11209
11210         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
11211         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
11212
11213         createmany -o $testdir1/test 512 || error "createmany failed"
11214
11215         # check samedir rename size
11216         mv ${testdir1}/test0 ${testdir1}/test_0
11217
11218         local testdir1_size=$(ls -l $DIR/${tdir} |
11219                 awk '/stats_testdir1/ {print $5}')
11220         local testdir2_size=$(ls -l $DIR/${tdir} |
11221                 awk '/stats_testdir2/ {print $5}')
11222
11223         testdir1_size=$(order_2 $testdir1_size)
11224         testdir2_size=$(order_2 $testdir2_size)
11225
11226         testdir1_size=$(size_in_KMGT $testdir1_size)
11227         testdir2_size=$(size_in_KMGT $testdir2_size)
11228
11229         echo "source rename dir size: ${testdir1_size}"
11230         echo "target rename dir size: ${testdir2_size}"
11231
11232         local cmd="do_facet $SINGLEMDS $LCTL "
11233         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
11234
11235         eval $cmd || error "$cmd failed"
11236         local samedir=$($cmd | grep 'same_dir')
11237         local same_sample=$(get_rename_size $testdir1_size)
11238         [ -z "$samedir" ] && error "samedir_rename_size count error"
11239         [[ $same_sample -eq 1 ]] ||
11240                 error "samedir_rename_size error $same_sample"
11241         echo "Check same dir rename stats success"
11242
11243         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11244
11245         # check crossdir rename size
11246         mv ${testdir1}/test_0 ${testdir2}/test_0
11247
11248         testdir1_size=$(ls -l $DIR/${tdir} |
11249                 awk '/stats_testdir1/ {print $5}')
11250         testdir2_size=$(ls -l $DIR/${tdir} |
11251                 awk '/stats_testdir2/ {print $5}')
11252
11253         testdir1_size=$(order_2 $testdir1_size)
11254         testdir2_size=$(order_2 $testdir2_size)
11255
11256         testdir1_size=$(size_in_KMGT $testdir1_size)
11257         testdir2_size=$(size_in_KMGT $testdir2_size)
11258
11259         echo "source rename dir size: ${testdir1_size}"
11260         echo "target rename dir size: ${testdir2_size}"
11261
11262         eval $cmd || error "$cmd failed"
11263         local crossdir=$($cmd | grep 'crossdir')
11264         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
11265         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
11266         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
11267         [[ $src_sample -eq 1 ]] ||
11268                 error "crossdir_rename_size error $src_sample"
11269         [[ $tgt_sample -eq 1 ]] ||
11270                 error "crossdir_rename_size error $tgt_sample"
11271         echo "Check cross dir rename stats success"
11272         rm -rf $DIR/${tdir}
11273 }
11274 run_test 133d "Verifying rename_stats ========================================"
11275
11276 test_133e() {
11277         remote_mds_nodsh && skip "remote MDS with nodsh"
11278         remote_ost_nodsh && skip "remote OST with nodsh"
11279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11280
11281         local testdir=$DIR/${tdir}/stats_testdir
11282         local ctr f0 f1 bs=32768 count=42 sum
11283
11284         mkdir -p ${testdir} || error "mkdir failed"
11285
11286         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
11287
11288         for ctr in {write,read}_bytes; do
11289                 sync
11290                 cancel_lru_locks osc
11291
11292                 do_facet ost1 $LCTL set_param -n \
11293                         "obdfilter.*.exports.clear=clear"
11294
11295                 if [ $ctr = write_bytes ]; then
11296                         f0=/dev/zero
11297                         f1=${testdir}/${tfile}
11298                 else
11299                         f0=${testdir}/${tfile}
11300                         f1=/dev/null
11301                 fi
11302
11303                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
11304                         error "dd failed"
11305                 sync
11306                 cancel_lru_locks osc
11307
11308                 sum=$(do_facet ost1 $LCTL get_param \
11309                         "obdfilter.*.exports.*.stats" |
11310                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
11311                                 $1 == ctr { sum += $7 }
11312                                 END { printf("%0.0f", sum) }')
11313
11314                 if ((sum != bs * count)); then
11315                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
11316                 fi
11317         done
11318
11319         rm -rf $DIR/${tdir}
11320 }
11321 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
11322
11323 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
11324
11325 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
11326 # not honor the -ignore_readdir_race option correctly. So we call
11327 # error_ignore() rather than error() in these cases. See LU-11152.
11328 error_133() {
11329         if (find --version; do_facet mds1 find --version) |
11330                 grep -q '\b4\.5\.1[1-4]\b'; then
11331                 error_ignore LU-11152 "$@"
11332         else
11333                 error "$@"
11334         fi
11335 }
11336
11337 test_133f() {
11338         # First without trusting modes.
11339         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
11340         echo "proc_dirs='$proc_dirs'"
11341         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
11342         find $proc_dirs -exec cat '{}' \; &> /dev/null
11343
11344         # Second verifying readability.
11345         $LCTL get_param -R '*' &> /dev/null
11346
11347         # Verifing writability with badarea_io.
11348         find $proc_dirs \
11349                 -ignore_readdir_race \
11350                 -type f \
11351                 -not -name force_lbug \
11352                 -not -name changelog_mask \
11353                 -exec badarea_io '{}' \; ||
11354                         error_133 "find $proc_dirs failed"
11355 }
11356 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
11357
11358 test_133g() {
11359         remote_mds_nodsh && skip "remote MDS with nodsh"
11360         remote_ost_nodsh && skip "remote OST with nodsh"
11361
11362         # eventually, this can also be replaced with "lctl get_param -R",
11363         # but not until that option is always available on the server
11364         local facet
11365         for facet in mds1 ost1; do
11366                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
11367                         skip_noexit "Too old lustre on $facet"
11368                 local facet_proc_dirs=$(do_facet $facet \
11369                                         \\\ls -d $proc_regexp 2>/dev/null)
11370                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11371                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11372                 do_facet $facet find $facet_proc_dirs \
11373                         ! -name req_history \
11374                         -exec cat '{}' \\\; &> /dev/null
11375
11376                 do_facet $facet find $facet_proc_dirs \
11377                         ! -name req_history \
11378                         -type f \
11379                         -exec cat '{}' \\\; &> /dev/null ||
11380                                 error "proc file read failed"
11381
11382                 do_facet $facet find $facet_proc_dirs \
11383                         -ignore_readdir_race \
11384                         -type f \
11385                         -not -name force_lbug \
11386                         -not -name changelog_mask \
11387                         -exec badarea_io '{}' \\\; ||
11388                                 error_133 "$facet find $facet_proc_dirs failed"
11389         done
11390
11391         # remount the FS in case writes/reads /proc break the FS
11392         cleanup || error "failed to unmount"
11393         setup || error "failed to setup"
11394         true
11395 }
11396 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
11397
11398 test_133h() {
11399         remote_mds_nodsh && skip "remote MDS with nodsh"
11400         remote_ost_nodsh && skip "remote OST with nodsh"
11401         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
11402                 skip "Need MDS version at least 2.9.54"
11403
11404         local facet
11405
11406         for facet in client mds1 ost1; do
11407                 local facet_proc_dirs=$(do_facet $facet \
11408                                         \\\ls -d $proc_regexp 2> /dev/null)
11409                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11410                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11411                 # Get the list of files that are missing the terminating newline
11412                 local missing=($(do_facet $facet \
11413                         find ${facet_proc_dirs} -type f \|              \
11414                                 while read F\; do                       \
11415                                         awk -v FS='\v' -v RS='\v\v'     \
11416                                         "'END { if(NR>0 &&              \
11417                                         \\\$NF !~ /.*\\\n\$/)           \
11418                                                 print FILENAME}'"       \
11419                                         '\$F'\;                         \
11420                                 done 2>/dev/null))
11421                 [ ${#missing[*]} -eq 0 ] ||
11422                         error "files do not end with newline: ${missing[*]}"
11423         done
11424 }
11425 run_test 133h "Proc files should end with newlines"
11426
11427 test_134a() {
11428         remote_mds_nodsh && skip "remote MDS with nodsh"
11429         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11430                 skip "Need MDS version at least 2.7.54"
11431
11432         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11433         cancel_lru_locks mdc
11434
11435         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11436         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11437         [ $unused -eq 0 ] || error "$unused locks are not cleared"
11438
11439         local nr=1000
11440         createmany -o $DIR/$tdir/f $nr ||
11441                 error "failed to create $nr files in $DIR/$tdir"
11442         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11443
11444         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
11445         do_facet mds1 $LCTL set_param fail_loc=0x327
11446         do_facet mds1 $LCTL set_param fail_val=500
11447         touch $DIR/$tdir/m
11448
11449         echo "sleep 10 seconds ..."
11450         sleep 10
11451         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
11452
11453         do_facet mds1 $LCTL set_param fail_loc=0
11454         do_facet mds1 $LCTL set_param fail_val=0
11455         [ $lck_cnt -lt $unused ] ||
11456                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
11457
11458         rm $DIR/$tdir/m
11459         unlinkmany $DIR/$tdir/f $nr
11460 }
11461 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
11462
11463 test_134b() {
11464         remote_mds_nodsh && skip "remote MDS with nodsh"
11465         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11466                 skip "Need MDS version at least 2.7.54"
11467
11468         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11469         cancel_lru_locks mdc
11470
11471         local low_wm=$(do_facet mds1 $LCTL get_param -n \
11472                         ldlm.lock_reclaim_threshold_mb)
11473         # disable reclaim temporarily
11474         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
11475
11476         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
11477         do_facet mds1 $LCTL set_param fail_loc=0x328
11478         do_facet mds1 $LCTL set_param fail_val=500
11479
11480         $LCTL set_param debug=+trace
11481
11482         local nr=600
11483         createmany -o $DIR/$tdir/f $nr &
11484         local create_pid=$!
11485
11486         echo "Sleep $TIMEOUT seconds ..."
11487         sleep $TIMEOUT
11488         if ! ps -p $create_pid  > /dev/null 2>&1; then
11489                 do_facet mds1 $LCTL set_param fail_loc=0
11490                 do_facet mds1 $LCTL set_param fail_val=0
11491                 do_facet mds1 $LCTL set_param \
11492                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
11493                 error "createmany finished incorrectly!"
11494         fi
11495         do_facet mds1 $LCTL set_param fail_loc=0
11496         do_facet mds1 $LCTL set_param fail_val=0
11497         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
11498         wait $create_pid || return 1
11499
11500         unlinkmany $DIR/$tdir/f $nr
11501 }
11502 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
11503
11504 test_140() { #bug-17379
11505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11506
11507         test_mkdir $DIR/$tdir
11508         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
11509         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
11510
11511         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
11512         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
11513         local i=0
11514         while i=$((i + 1)); do
11515                 test_mkdir $i
11516                 cd $i || error "Changing to $i"
11517                 ln -s ../stat stat || error "Creating stat symlink"
11518                 # Read the symlink until ELOOP present,
11519                 # not LBUGing the system is considered success,
11520                 # we didn't overrun the stack.
11521                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
11522                 if [ $ret -ne 0 ]; then
11523                         if [ $ret -eq 40 ]; then
11524                                 break  # -ELOOP
11525                         else
11526                                 error "Open stat symlink"
11527                                         return
11528                         fi
11529                 fi
11530         done
11531         i=$((i - 1))
11532         echo "The symlink depth = $i"
11533         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
11534                 error "Invalid symlink depth"
11535
11536         # Test recursive symlink
11537         ln -s symlink_self symlink_self
11538         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
11539         echo "open symlink_self returns $ret"
11540         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
11541 }
11542 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
11543
11544 test_150() {
11545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11546
11547         local TF="$TMP/$tfile"
11548
11549         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
11550         cp $TF $DIR/$tfile
11551         cancel_lru_locks $OSC
11552         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
11553         remount_client $MOUNT
11554         df -P $MOUNT
11555         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
11556
11557         $TRUNCATE $TF 6000
11558         $TRUNCATE $DIR/$tfile 6000
11559         cancel_lru_locks $OSC
11560         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
11561
11562         echo "12345" >>$TF
11563         echo "12345" >>$DIR/$tfile
11564         cancel_lru_locks $OSC
11565         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
11566
11567         echo "12345" >>$TF
11568         echo "12345" >>$DIR/$tfile
11569         cancel_lru_locks $OSC
11570         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
11571
11572         rm -f $TF
11573         true
11574 }
11575 run_test 150 "truncate/append tests"
11576
11577 #LU-2902 roc_hit was not able to read all values from lproc
11578 function roc_hit_init() {
11579         local list=$(comma_list $(osts_nodes))
11580         local dir=$DIR/$tdir-check
11581         local file=$dir/$tfile
11582         local BEFORE
11583         local AFTER
11584         local idx
11585
11586         test_mkdir $dir
11587         #use setstripe to do a write to every ost
11588         for i in $(seq 0 $((OSTCOUNT-1))); do
11589                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
11590                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
11591                 idx=$(printf %04x $i)
11592                 BEFORE=$(get_osd_param $list *OST*$idx stats |
11593                         awk '$1 == "cache_access" {sum += $7}
11594                                 END { printf("%0.0f", sum) }')
11595
11596                 cancel_lru_locks osc
11597                 cat $file >/dev/null
11598
11599                 AFTER=$(get_osd_param $list *OST*$idx stats |
11600                         awk '$1 == "cache_access" {sum += $7}
11601                                 END { printf("%0.0f", sum) }')
11602
11603                 echo BEFORE:$BEFORE AFTER:$AFTER
11604                 if ! let "AFTER - BEFORE == 4"; then
11605                         rm -rf $dir
11606                         error "roc_hit is not safe to use"
11607                 fi
11608                 rm $file
11609         done
11610
11611         rm -rf $dir
11612 }
11613
11614 function roc_hit() {
11615         local list=$(comma_list $(osts_nodes))
11616         echo $(get_osd_param $list '' stats |
11617                 awk '$1 == "cache_hit" {sum += $7}
11618                         END { printf("%0.0f", sum) }')
11619 }
11620
11621 function set_cache() {
11622         local on=1
11623
11624         if [ "$2" == "off" ]; then
11625                 on=0;
11626         fi
11627         local list=$(comma_list $(osts_nodes))
11628         set_osd_param $list '' $1_cache_enable $on
11629
11630         cancel_lru_locks osc
11631 }
11632
11633 test_151() {
11634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11635         remote_ost_nodsh && skip "remote OST with nodsh"
11636
11637         local CPAGES=3
11638         local list=$(comma_list $(osts_nodes))
11639
11640         # check whether obdfilter is cache capable at all
11641         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
11642                 skip "not cache-capable obdfilter"
11643         fi
11644
11645         # check cache is enabled on all obdfilters
11646         if get_osd_param $list '' read_cache_enable | grep 0; then
11647                 skip "oss cache is disabled"
11648         fi
11649
11650         set_osd_param $list '' writethrough_cache_enable 1
11651
11652         # check write cache is enabled on all obdfilters
11653         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
11654                 skip "oss write cache is NOT enabled"
11655         fi
11656
11657         roc_hit_init
11658
11659         #define OBD_FAIL_OBD_NO_LRU  0x609
11660         do_nodes $list $LCTL set_param fail_loc=0x609
11661
11662         # pages should be in the case right after write
11663         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
11664                 error "dd failed"
11665
11666         local BEFORE=$(roc_hit)
11667         cancel_lru_locks osc
11668         cat $DIR/$tfile >/dev/null
11669         local AFTER=$(roc_hit)
11670
11671         do_nodes $list $LCTL set_param fail_loc=0
11672
11673         if ! let "AFTER - BEFORE == CPAGES"; then
11674                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
11675         fi
11676
11677         # the following read invalidates the cache
11678         cancel_lru_locks osc
11679         set_osd_param $list '' read_cache_enable 0
11680         cat $DIR/$tfile >/dev/null
11681
11682         # now data shouldn't be found in the cache
11683         BEFORE=$(roc_hit)
11684         cancel_lru_locks osc
11685         cat $DIR/$tfile >/dev/null
11686         AFTER=$(roc_hit)
11687         if let "AFTER - BEFORE != 0"; then
11688                 error "IN CACHE: before: $BEFORE, after: $AFTER"
11689         fi
11690
11691         set_osd_param $list '' read_cache_enable 1
11692         rm -f $DIR/$tfile
11693 }
11694 run_test 151 "test cache on oss and controls ==============================="
11695
11696 test_152() {
11697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11698
11699         local TF="$TMP/$tfile"
11700
11701         # simulate ENOMEM during write
11702 #define OBD_FAIL_OST_NOMEM      0x226
11703         lctl set_param fail_loc=0x80000226
11704         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
11705         cp $TF $DIR/$tfile
11706         sync || error "sync failed"
11707         lctl set_param fail_loc=0
11708
11709         # discard client's cache
11710         cancel_lru_locks osc
11711
11712         # simulate ENOMEM during read
11713         lctl set_param fail_loc=0x80000226
11714         cmp $TF $DIR/$tfile || error "cmp failed"
11715         lctl set_param fail_loc=0
11716
11717         rm -f $TF
11718 }
11719 run_test 152 "test read/write with enomem ============================"
11720
11721 test_153() {
11722         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
11723 }
11724 run_test 153 "test if fdatasync does not crash ======================="
11725
11726 dot_lustre_fid_permission_check() {
11727         local fid=$1
11728         local ffid=$MOUNT/.lustre/fid/$fid
11729         local test_dir=$2
11730
11731         echo "stat fid $fid"
11732         stat $ffid > /dev/null || error "stat $ffid failed."
11733         echo "touch fid $fid"
11734         touch $ffid || error "touch $ffid failed."
11735         echo "write to fid $fid"
11736         cat /etc/hosts > $ffid || error "write $ffid failed."
11737         echo "read fid $fid"
11738         diff /etc/hosts $ffid || error "read $ffid failed."
11739         echo "append write to fid $fid"
11740         cat /etc/hosts >> $ffid || error "append write $ffid failed."
11741         echo "rename fid $fid"
11742         mv $ffid $test_dir/$tfile.1 &&
11743                 error "rename $ffid to $tfile.1 should fail."
11744         touch $test_dir/$tfile.1
11745         mv $test_dir/$tfile.1 $ffid &&
11746                 error "rename $tfile.1 to $ffid should fail."
11747         rm -f $test_dir/$tfile.1
11748         echo "truncate fid $fid"
11749         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
11750         echo "link fid $fid"
11751         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
11752         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
11753                 echo "setfacl fid $fid"
11754                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
11755                 echo "getfacl fid $fid"
11756                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
11757         fi
11758         echo "unlink fid $fid"
11759         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
11760         echo "mknod fid $fid"
11761         mknod $ffid c 1 3 && error "mknod $ffid should fail."
11762
11763         fid=[0xf00000400:0x1:0x0]
11764         ffid=$MOUNT/.lustre/fid/$fid
11765
11766         echo "stat non-exist fid $fid"
11767         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
11768         echo "write to non-exist fid $fid"
11769         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
11770         echo "link new fid $fid"
11771         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
11772
11773         mkdir -p $test_dir/$tdir
11774         touch $test_dir/$tdir/$tfile
11775         fid=$($LFS path2fid $test_dir/$tdir)
11776         rc=$?
11777         [ $rc -ne 0 ] &&
11778                 error "error: could not get fid for $test_dir/$dir/$tfile."
11779
11780         ffid=$MOUNT/.lustre/fid/$fid
11781
11782         echo "ls $fid"
11783         ls $ffid > /dev/null || error "ls $ffid failed."
11784         echo "touch $fid/$tfile.1"
11785         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
11786
11787         echo "touch $MOUNT/.lustre/fid/$tfile"
11788         touch $MOUNT/.lustre/fid/$tfile && \
11789                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
11790
11791         echo "setxattr to $MOUNT/.lustre/fid"
11792         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
11793
11794         echo "listxattr for $MOUNT/.lustre/fid"
11795         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
11796
11797         echo "delxattr from $MOUNT/.lustre/fid"
11798         setfattr -x trusted.name1 $MOUNT/.lustre/fid
11799
11800         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
11801         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
11802                 error "touch invalid fid should fail."
11803
11804         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
11805         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
11806                 error "touch non-normal fid should fail."
11807
11808         echo "rename $tdir to $MOUNT/.lustre/fid"
11809         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
11810                 error "rename to $MOUNT/.lustre/fid should fail."
11811
11812         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
11813         then            # LU-3547
11814                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
11815                 local new_obf_mode=777
11816
11817                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
11818                 chmod $new_obf_mode $DIR/.lustre/fid ||
11819                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
11820
11821                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
11822                 [ $obf_mode -eq $new_obf_mode ] ||
11823                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
11824
11825                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
11826                 chmod $old_obf_mode $DIR/.lustre/fid ||
11827                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
11828         fi
11829
11830         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
11831         fid=$($LFS path2fid $test_dir/$tfile-2)
11832
11833         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
11834         then # LU-5424
11835                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
11836                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
11837                         error "create lov data thru .lustre failed"
11838         fi
11839         echo "cp /etc/passwd $test_dir/$tfile-2"
11840         cp /etc/passwd $test_dir/$tfile-2 ||
11841                 error "copy to $test_dir/$tfile-2 failed."
11842         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
11843         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
11844                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
11845
11846         rm -rf $test_dir/tfile.lnk
11847         rm -rf $test_dir/$tfile-2
11848 }
11849
11850 test_154A() {
11851         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11852                 skip "Need MDS version at least 2.4.1"
11853
11854         local tf=$DIR/$tfile
11855         touch $tf
11856
11857         local fid=$($LFS path2fid $tf)
11858         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
11859
11860         # check that we get the same pathname back
11861         local found=$($LFS fid2path $MOUNT "$fid")
11862         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
11863         [ "$found" == "$tf" ] ||
11864                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
11865 }
11866 run_test 154A "lfs path2fid and fid2path basic checks"
11867
11868 test_154B() {
11869         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11870                 skip "Need MDS version at least 2.4.1"
11871
11872         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
11873         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
11874         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
11875         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
11876
11877         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
11878         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
11879
11880         # check that we get the same pathname
11881         echo "PFID: $PFID, name: $name"
11882         local FOUND=$($LFS fid2path $MOUNT "$PFID")
11883         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
11884         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
11885                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
11886
11887         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
11888 }
11889 run_test 154B "verify the ll_decode_linkea tool"
11890
11891 test_154a() {
11892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11893         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11894         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
11895                 skip "Need MDS version at least 2.2.51"
11896         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11897
11898         cp /etc/hosts $DIR/$tfile
11899
11900         fid=$($LFS path2fid $DIR/$tfile)
11901         rc=$?
11902         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
11903
11904         dot_lustre_fid_permission_check "$fid" $DIR ||
11905                 error "dot lustre permission check $fid failed"
11906
11907         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
11908
11909         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
11910
11911         touch $MOUNT/.lustre/file &&
11912                 error "creation is not allowed under .lustre"
11913
11914         mkdir $MOUNT/.lustre/dir &&
11915                 error "mkdir is not allowed under .lustre"
11916
11917         rm -rf $DIR/$tfile
11918 }
11919 run_test 154a "Open-by-FID"
11920
11921 test_154b() {
11922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11923         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11924         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
11925         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
11926                 skip "Need MDS version at least 2.2.51"
11927
11928         local remote_dir=$DIR/$tdir/remote_dir
11929         local MDTIDX=1
11930         local rc=0
11931
11932         mkdir -p $DIR/$tdir
11933         $LFS mkdir -i $MDTIDX $remote_dir ||
11934                 error "create remote directory failed"
11935
11936         cp /etc/hosts $remote_dir/$tfile
11937
11938         fid=$($LFS path2fid $remote_dir/$tfile)
11939         rc=$?
11940         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
11941
11942         dot_lustre_fid_permission_check "$fid" $remote_dir ||
11943                 error "dot lustre permission check $fid failed"
11944         rm -rf $DIR/$tdir
11945 }
11946 run_test 154b "Open-by-FID for remote directory"
11947
11948 test_154c() {
11949         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11950                 skip "Need MDS version at least 2.4.1"
11951
11952         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
11953         local FID1=$($LFS path2fid $DIR/$tfile.1)
11954         local FID2=$($LFS path2fid $DIR/$tfile.2)
11955         local FID3=$($LFS path2fid $DIR/$tfile.3)
11956
11957         local N=1
11958         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
11959                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
11960                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
11961                 local want=FID$N
11962                 [ "$FID" = "${!want}" ] ||
11963                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
11964                 N=$((N + 1))
11965         done
11966
11967         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
11968         do
11969                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
11970                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
11971                 N=$((N + 1))
11972         done
11973 }
11974 run_test 154c "lfs path2fid and fid2path multiple arguments"
11975
11976 test_154d() {
11977         remote_mds_nodsh && skip "remote MDS with nodsh"
11978         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
11979                 skip "Need MDS version at least 2.5.53"
11980
11981         if remote_mds; then
11982                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
11983         else
11984                 nid="0@lo"
11985         fi
11986         local proc_ofile="mdt.*.exports.'$nid'.open_files"
11987         local fd
11988         local cmd
11989
11990         rm -f $DIR/$tfile
11991         touch $DIR/$tfile
11992
11993         local fid=$($LFS path2fid $DIR/$tfile)
11994         # Open the file
11995         fd=$(free_fd)
11996         cmd="exec $fd<$DIR/$tfile"
11997         eval $cmd
11998         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
11999         echo "$fid_list" | grep "$fid"
12000         rc=$?
12001
12002         cmd="exec $fd>/dev/null"
12003         eval $cmd
12004         if [ $rc -ne 0 ]; then
12005                 error "FID $fid not found in open files list $fid_list"
12006         fi
12007 }
12008 run_test 154d "Verify open file fid"
12009
12010 test_154e()
12011 {
12012         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
12013                 skip "Need MDS version at least 2.6.50"
12014
12015         if ls -a $MOUNT | grep -q '^\.lustre$'; then
12016                 error ".lustre returned by readdir"
12017         fi
12018 }
12019 run_test 154e ".lustre is not returned by readdir"
12020
12021 test_154f() {
12022         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12023
12024         # create parent directory on a single MDT to avoid cross-MDT hardlinks
12025         test_mkdir -p -c1 $DIR/$tdir/d
12026         # test dirs inherit from its stripe
12027         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
12028         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
12029         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
12030         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
12031         touch $DIR/f
12032
12033         # get fid of parents
12034         local FID0=$($LFS path2fid $DIR/$tdir/d)
12035         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
12036         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
12037         local FID3=$($LFS path2fid $DIR)
12038
12039         # check that path2fid --parents returns expected <parent_fid>/name
12040         # 1) test for a directory (single parent)
12041         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
12042         [ "$parent" == "$FID0/foo1" ] ||
12043                 error "expected parent: $FID0/foo1, got: $parent"
12044
12045         # 2) test for a file with nlink > 1 (multiple parents)
12046         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
12047         echo "$parent" | grep -F "$FID1/$tfile" ||
12048                 error "$FID1/$tfile not returned in parent list"
12049         echo "$parent" | grep -F "$FID2/link" ||
12050                 error "$FID2/link not returned in parent list"
12051
12052         # 3) get parent by fid
12053         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
12054         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12055         echo "$parent" | grep -F "$FID1/$tfile" ||
12056                 error "$FID1/$tfile not returned in parent list (by fid)"
12057         echo "$parent" | grep -F "$FID2/link" ||
12058                 error "$FID2/link not returned in parent list (by fid)"
12059
12060         # 4) test for entry in root directory
12061         parent=$($LFS path2fid --parents $DIR/f)
12062         echo "$parent" | grep -F "$FID3/f" ||
12063                 error "$FID3/f not returned in parent list"
12064
12065         # 5) test it on root directory
12066         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
12067                 error "$MOUNT should not have parents"
12068
12069         # enable xattr caching and check that linkea is correctly updated
12070         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12071         save_lustre_params client "llite.*.xattr_cache" > $save
12072         lctl set_param llite.*.xattr_cache 1
12073
12074         # 6.1) linkea update on rename
12075         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
12076
12077         # get parents by fid
12078         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12079         # foo1 should no longer be returned in parent list
12080         echo "$parent" | grep -F "$FID1" &&
12081                 error "$FID1 should no longer be in parent list"
12082         # the new path should appear
12083         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
12084                 error "$FID2/$tfile.moved is not in parent list"
12085
12086         # 6.2) linkea update on unlink
12087         rm -f $DIR/$tdir/d/foo2/link
12088         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12089         # foo2/link should no longer be returned in parent list
12090         echo "$parent" | grep -F "$FID2/link" &&
12091                 error "$FID2/link should no longer be in parent list"
12092         true
12093
12094         rm -f $DIR/f
12095         restore_lustre_params < $save
12096         rm -f $save
12097 }
12098 run_test 154f "get parent fids by reading link ea"
12099
12100 test_154g()
12101 {
12102         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12103         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
12104            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
12105                 skip "Need MDS version at least 2.6.92"
12106
12107         mkdir -p $DIR/$tdir
12108         llapi_fid_test -d $DIR/$tdir
12109 }
12110 run_test 154g "various llapi FID tests"
12111
12112 test_155_small_load() {
12113     local temp=$TMP/$tfile
12114     local file=$DIR/$tfile
12115
12116     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
12117         error "dd of=$temp bs=6096 count=1 failed"
12118     cp $temp $file
12119     cancel_lru_locks $OSC
12120     cmp $temp $file || error "$temp $file differ"
12121
12122     $TRUNCATE $temp 6000
12123     $TRUNCATE $file 6000
12124     cmp $temp $file || error "$temp $file differ (truncate1)"
12125
12126     echo "12345" >>$temp
12127     echo "12345" >>$file
12128     cmp $temp $file || error "$temp $file differ (append1)"
12129
12130     echo "12345" >>$temp
12131     echo "12345" >>$file
12132     cmp $temp $file || error "$temp $file differ (append2)"
12133
12134     rm -f $temp $file
12135     true
12136 }
12137
12138 test_155_big_load() {
12139         remote_ost_nodsh && skip "remote OST with nodsh"
12140
12141         local temp=$TMP/$tfile
12142         local file=$DIR/$tfile
12143
12144         free_min_max
12145         local cache_size=$(do_facet ost$((MAXI+1)) \
12146                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
12147         local large_file_size=$((cache_size * 2))
12148
12149         echo "OSS cache size: $cache_size KB"
12150         echo "Large file size: $large_file_size KB"
12151
12152         [ $MAXV -le $large_file_size ] &&
12153                 skip_env "max available OST size needs > $large_file_size KB"
12154
12155         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
12156
12157         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
12158                 error "dd of=$temp bs=$large_file_size count=1k failed"
12159         cp $temp $file
12160         ls -lh $temp $file
12161         cancel_lru_locks osc
12162         cmp $temp $file || error "$temp $file differ"
12163
12164         rm -f $temp $file
12165         true
12166 }
12167
12168 save_writethrough() {
12169         local facets=$(get_facets OST)
12170
12171         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
12172 }
12173
12174 test_155a() {
12175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12176
12177         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12178
12179         save_writethrough $p
12180
12181         set_cache read on
12182         set_cache writethrough on
12183         test_155_small_load
12184         restore_lustre_params < $p
12185         rm -f $p
12186 }
12187 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
12188
12189 test_155b() {
12190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12191
12192         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12193
12194         save_writethrough $p
12195
12196         set_cache read on
12197         set_cache writethrough off
12198         test_155_small_load
12199         restore_lustre_params < $p
12200         rm -f $p
12201 }
12202 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
12203
12204 test_155c() {
12205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12206
12207         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12208
12209         save_writethrough $p
12210
12211         set_cache read off
12212         set_cache writethrough on
12213         test_155_small_load
12214         restore_lustre_params < $p
12215         rm -f $p
12216 }
12217 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
12218
12219 test_155d() {
12220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12221
12222         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12223
12224         save_writethrough $p
12225
12226         set_cache read off
12227         set_cache writethrough off
12228         test_155_small_load
12229         restore_lustre_params < $p
12230         rm -f $p
12231 }
12232 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
12233
12234 test_155e() {
12235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12236
12237         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12238
12239         save_writethrough $p
12240
12241         set_cache read on
12242         set_cache writethrough on
12243         test_155_big_load
12244         restore_lustre_params < $p
12245         rm -f $p
12246 }
12247 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
12248
12249 test_155f() {
12250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12251
12252         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12253
12254         save_writethrough $p
12255
12256         set_cache read on
12257         set_cache writethrough off
12258         test_155_big_load
12259         restore_lustre_params < $p
12260         rm -f $p
12261 }
12262 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
12263
12264 test_155g() {
12265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12266
12267         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12268
12269         save_writethrough $p
12270
12271         set_cache read off
12272         set_cache writethrough on
12273         test_155_big_load
12274         restore_lustre_params < $p
12275         rm -f $p
12276 }
12277 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
12278
12279 test_155h() {
12280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12281
12282         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12283
12284         save_writethrough $p
12285
12286         set_cache read off
12287         set_cache writethrough off
12288         test_155_big_load
12289         restore_lustre_params < $p
12290         rm -f $p
12291 }
12292 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
12293
12294 test_156() {
12295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12296         remote_ost_nodsh && skip "remote OST with nodsh"
12297         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
12298                 skip "stats not implemented on old servers"
12299         [ "$ost1_FSTYPE" = "zfs" ] &&
12300                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
12301
12302         local CPAGES=3
12303         local BEFORE
12304         local AFTER
12305         local file="$DIR/$tfile"
12306         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12307
12308         save_writethrough $p
12309         roc_hit_init
12310
12311         log "Turn on read and write cache"
12312         set_cache read on
12313         set_cache writethrough on
12314
12315         log "Write data and read it back."
12316         log "Read should be satisfied from the cache."
12317         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
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 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 == CPAGES"; then
12334                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12335         else
12336                 log "cache hits:: before: $BEFORE, after: $AFTER"
12337         fi
12338
12339         log "Turn off the read cache and turn on the write cache"
12340         set_cache read off
12341         set_cache writethrough on
12342
12343         log "Read again; it should be satisfied from the cache."
12344         BEFORE=$(roc_hit)
12345         cancel_lru_locks osc
12346         cat $file >/dev/null
12347         AFTER=$(roc_hit)
12348         if ! let "AFTER - BEFORE == CPAGES"; then
12349                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12350         else
12351                 log "cache hits:: before: $BEFORE, after: $AFTER"
12352         fi
12353
12354         log "Read again; it should not be satisfied from the cache."
12355         BEFORE=$AFTER
12356         cancel_lru_locks osc
12357         cat $file >/dev/null
12358         AFTER=$(roc_hit)
12359         if ! let "AFTER - BEFORE == 0"; then
12360                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12361         else
12362                 log "cache hits:: before: $BEFORE, after: $AFTER"
12363         fi
12364
12365         log "Write data and read it back."
12366         log "Read should be satisfied from the cache."
12367         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12368         BEFORE=$(roc_hit)
12369         cancel_lru_locks osc
12370         cat $file >/dev/null
12371         AFTER=$(roc_hit)
12372         if ! let "AFTER - BEFORE == CPAGES"; then
12373                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12374         else
12375                 log "cache hits:: before: $BEFORE, after: $AFTER"
12376         fi
12377
12378         log "Read again; it should not be satisfied from the cache."
12379         BEFORE=$AFTER
12380         cancel_lru_locks osc
12381         cat $file >/dev/null
12382         AFTER=$(roc_hit)
12383         if ! let "AFTER - BEFORE == 0"; then
12384                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12385         else
12386                 log "cache hits:: before: $BEFORE, after: $AFTER"
12387         fi
12388
12389         log "Turn off read and write cache"
12390         set_cache read off
12391         set_cache writethrough off
12392
12393         log "Write data and read it back"
12394         log "It should not be satisfied from the cache."
12395         rm -f $file
12396         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12397         cancel_lru_locks osc
12398         BEFORE=$(roc_hit)
12399         cat $file >/dev/null
12400         AFTER=$(roc_hit)
12401         if ! let "AFTER - BEFORE == 0"; then
12402                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12403         else
12404                 log "cache hits:: before: $BEFORE, after: $AFTER"
12405         fi
12406
12407         log "Turn on the read cache and turn off the write cache"
12408         set_cache read on
12409         set_cache writethrough off
12410
12411         log "Write data and read it back"
12412         log "It should not be satisfied from the cache."
12413         rm -f $file
12414         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12415         BEFORE=$(roc_hit)
12416         cancel_lru_locks osc
12417         cat $file >/dev/null
12418         AFTER=$(roc_hit)
12419         if ! let "AFTER - BEFORE == 0"; then
12420                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12421         else
12422                 log "cache hits:: before: $BEFORE, after: $AFTER"
12423         fi
12424
12425         log "Read again; it should be satisfied from the cache."
12426         BEFORE=$(roc_hit)
12427         cancel_lru_locks osc
12428         cat $file >/dev/null
12429         AFTER=$(roc_hit)
12430         if ! let "AFTER - BEFORE == CPAGES"; then
12431                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12432         else
12433                 log "cache hits:: before: $BEFORE, after: $AFTER"
12434         fi
12435
12436         restore_lustre_params < $p
12437         rm -f $p $file
12438 }
12439 run_test 156 "Verification of tunables"
12440
12441 test_160a() {
12442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12443         remote_mds_nodsh && skip "remote MDS with nodsh"
12444         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12445                 skip "Need MDS version at least 2.2.0"
12446
12447         changelog_register || error "changelog_register failed"
12448         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12449         changelog_users $SINGLEMDS | grep -q $cl_user ||
12450                 error "User $cl_user not found in changelog_users"
12451
12452         # change something
12453         test_mkdir -p $DIR/$tdir/pics/2008/zachy
12454         changelog_clear 0 || error "changelog_clear failed"
12455         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
12456         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
12457         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
12458         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
12459         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
12460         rm $DIR/$tdir/pics/desktop.jpg
12461
12462         changelog_dump | tail -10
12463
12464         echo "verifying changelog mask"
12465         changelog_chmask "-MKDIR"
12466         changelog_chmask "-CLOSE"
12467
12468         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
12469         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
12470
12471         changelog_chmask "+MKDIR"
12472         changelog_chmask "+CLOSE"
12473
12474         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
12475         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
12476
12477         changelog_dump | tail -10
12478         MKDIRS=$(changelog_dump | grep -c "MKDIR")
12479         CLOSES=$(changelog_dump | grep -c "CLOSE")
12480         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
12481         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
12482
12483         # verify contents
12484         echo "verifying target fid"
12485         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
12486         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
12487         [ "$fidc" == "$fidf" ] ||
12488                 error "changelog '$tfile' fid $fidc != file fid $fidf"
12489         echo "verifying parent fid"
12490         # The FID returned from the Changelog may be the directory shard on
12491         # a different MDT, and not the FID returned by path2fid on the parent.
12492         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
12493         # since this is what will matter when recreating this file in the tree.
12494         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
12495         local pathp=$($LFS fid2path $MOUNT "$fidp")
12496         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
12497                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
12498
12499         echo "getting records for $cl_user"
12500         changelog_users $SINGLEMDS
12501         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
12502         local nclr=3
12503         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
12504                 error "changelog_clear failed"
12505         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
12506         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
12507         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
12508                 error "user index expect $user_rec1 + $nclr != $user_rec2"
12509
12510         local min0_rec=$(changelog_users $SINGLEMDS |
12511                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
12512         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
12513                           awk '{ print $1; exit; }')
12514
12515         changelog_dump | tail -n 5
12516         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
12517         [ $first_rec == $((min0_rec + 1)) ] ||
12518                 error "first index should be $min0_rec + 1 not $first_rec"
12519
12520         # LU-3446 changelog index reset on MDT restart
12521         local cur_rec1=$(changelog_users $SINGLEMDS |
12522                          awk '/^current.index:/ { print $NF }')
12523         changelog_clear 0 ||
12524                 error "clear all changelog records for $cl_user failed"
12525         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
12526         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
12527                 error "Fail to start $SINGLEMDS"
12528         local cur_rec2=$(changelog_users $SINGLEMDS |
12529                          awk '/^current.index:/ { print $NF }')
12530         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
12531         [ $cur_rec1 == $cur_rec2 ] ||
12532                 error "current index should be $cur_rec1 not $cur_rec2"
12533
12534         echo "verifying users from this test are deregistered"
12535         changelog_deregister || error "changelog_deregister failed"
12536         changelog_users $SINGLEMDS | grep -q $cl_user &&
12537                 error "User '$cl_user' still in changelog_users"
12538
12539         # lctl get_param -n mdd.*.changelog_users
12540         # current index: 144
12541         # ID    index (idle seconds)
12542         # cl3   144 (2)
12543         if ! changelog_users $SINGLEMDS | grep "^cl"; then
12544                 # this is the normal case where all users were deregistered
12545                 # make sure no new records are added when no users are present
12546                 local last_rec1=$(changelog_users $SINGLEMDS |
12547                                   awk '/^current.index:/ { print $NF }')
12548                 touch $DIR/$tdir/chloe
12549                 local last_rec2=$(changelog_users $SINGLEMDS |
12550                                   awk '/^current.index:/ { print $NF }')
12551                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
12552                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
12553         else
12554                 # any changelog users must be leftovers from a previous test
12555                 changelog_users $SINGLEMDS
12556                 echo "other changelog users; can't verify off"
12557         fi
12558 }
12559 run_test 160a "changelog sanity"
12560
12561 test_160b() { # LU-3587
12562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12563         remote_mds_nodsh && skip "remote MDS with nodsh"
12564         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12565                 skip "Need MDS version at least 2.2.0"
12566
12567         changelog_register || error "changelog_register failed"
12568         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12569         changelog_users $SINGLEMDS | grep -q $cl_user ||
12570                 error "User '$cl_user' not found in changelog_users"
12571
12572         local longname1=$(str_repeat a 255)
12573         local longname2=$(str_repeat b 255)
12574
12575         cd $DIR
12576         echo "creating very long named file"
12577         touch $longname1 || error "create of '$longname1' failed"
12578         echo "renaming very long named file"
12579         mv $longname1 $longname2
12580
12581         changelog_dump | grep RENME | tail -n 5
12582         rm -f $longname2
12583 }
12584 run_test 160b "Verify that very long rename doesn't crash in changelog"
12585
12586 test_160c() {
12587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12588         remote_mds_nodsh && skip "remote MDS with nodsh"
12589
12590         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
12591                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
12592                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
12593                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
12594
12595         local rc=0
12596
12597         # Registration step
12598         changelog_register || error "changelog_register failed"
12599
12600         rm -rf $DIR/$tdir
12601         mkdir -p $DIR/$tdir
12602         $MCREATE $DIR/$tdir/foo_160c
12603         changelog_chmask "-TRUNC"
12604         $TRUNCATE $DIR/$tdir/foo_160c 200
12605         changelog_chmask "+TRUNC"
12606         $TRUNCATE $DIR/$tdir/foo_160c 199
12607         changelog_dump | tail -n 5
12608         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
12609         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
12610 }
12611 run_test 160c "verify that changelog log catch the truncate event"
12612
12613 test_160d() {
12614         remote_mds_nodsh && skip "remote MDS with nodsh"
12615         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
12616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12617         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
12618                 skip "Need MDS version at least 2.7.60"
12619
12620         # Registration step
12621         changelog_register || error "changelog_register failed"
12622
12623         mkdir -p $DIR/$tdir/migrate_dir
12624         changelog_clear 0 || error "changelog_clear failed"
12625
12626         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
12627         changelog_dump | tail -n 5
12628         local migrates=$(changelog_dump | grep -c "MIGRT")
12629         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
12630 }
12631 run_test 160d "verify that changelog log catch the migrate event"
12632
12633 test_160e() {
12634         remote_mds_nodsh && skip "remote MDS with nodsh"
12635
12636         # Create a user
12637         changelog_register || error "changelog_register failed"
12638
12639         # Delete a future user (expect fail)
12640         local MDT0=$(facet_svc $SINGLEMDS)
12641         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
12642         local rc=$?
12643
12644         if [ $rc -eq 0 ]; then
12645                 error "Deleted non-existant user cl77"
12646         elif [ $rc -ne 2 ]; then
12647                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
12648         fi
12649
12650         # Clear to a bad index (1 billion should be safe)
12651         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
12652         rc=$?
12653
12654         if [ $rc -eq 0 ]; then
12655                 error "Successfully cleared to invalid CL index"
12656         elif [ $rc -ne 22 ]; then
12657                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
12658         fi
12659 }
12660 run_test 160e "changelog negative testing (should return errors)"
12661
12662 test_160f() {
12663         remote_mds_nodsh && skip "remote MDS with nodsh" && return
12664         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12665                 skip "Need MDS version at least 2.10.56"
12666
12667         local mdts=$(comma_list $(mdts_nodes))
12668
12669         # Create a user
12670         changelog_register || error "first changelog_register failed"
12671         changelog_register || error "second changelog_register failed"
12672         local cl_users
12673         declare -A cl_user1
12674         declare -A cl_user2
12675         local user_rec1
12676         local user_rec2
12677         local i
12678
12679         # generate some changelog records to accumulate on each MDT
12680         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
12681         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12682                 error "create $DIR/$tdir/$tfile failed"
12683
12684         # check changelogs have been generated
12685         local nbcl=$(changelog_dump | wc -l)
12686         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12687
12688         for param in "changelog_max_idle_time=10" \
12689                      "changelog_gc=1" \
12690                      "changelog_min_gc_interval=2" \
12691                      "changelog_min_free_cat_entries=3"; do
12692                 local MDT0=$(facet_svc $SINGLEMDS)
12693                 local var="${param%=*}"
12694                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12695
12696                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12697                 do_nodes $mdts $LCTL set_param mdd.*.$param
12698         done
12699
12700         # force cl_user2 to be idle (1st part)
12701         sleep 9
12702
12703         # simulate changelog catalog almost full
12704         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
12705         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
12706
12707         for i in $(seq $MDSCOUNT); do
12708                 cl_users=(${CL_USERS[mds$i]})
12709                 cl_user1[mds$i]="${cl_users[0]}"
12710                 cl_user2[mds$i]="${cl_users[1]}"
12711
12712                 [ -n "${cl_user1[mds$i]}" ] ||
12713                         error "mds$i: no user registered"
12714                 [ -n "${cl_user2[mds$i]}" ] ||
12715                         error "mds$i: only ${cl_user2[mds$i]} is registered"
12716
12717                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12718                 [ -n "$user_rec1" ] ||
12719                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12720                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12721                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12722                 [ -n "$user_rec2" ] ||
12723                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12724                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12725                      "$user_rec1 + 2 == $user_rec2"
12726                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12727                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12728                               "$user_rec1 + 2, but is $user_rec2"
12729                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12730                 [ -n "$user_rec2" ] ||
12731                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12732                 [ $user_rec1 == $user_rec2 ] ||
12733                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12734                               "$user_rec1, but is $user_rec2"
12735         done
12736
12737         # force cl_user2 to be idle (2nd part) and to reach
12738         # changelog_max_idle_time
12739         sleep 2
12740
12741         # generate one more changelog to trigger fail_loc
12742         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12743                 error "create $DIR/$tdir/${tfile}bis failed"
12744
12745         # ensure gc thread is done
12746         for i in $(mdts_nodes); do
12747                 wait_update $i \
12748                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
12749                         error "$i: GC-thread not done"
12750         done
12751
12752         local first_rec
12753         for i in $(seq $MDSCOUNT); do
12754                 # check cl_user1 still registered
12755                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
12756                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12757                 # check cl_user2 unregistered
12758                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
12759                         error "mds$i: User ${cl_user2[mds$i]} still registered"
12760
12761                 # check changelogs are present and starting at $user_rec1 + 1
12762                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12763                 [ -n "$user_rec1" ] ||
12764                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12765                 first_rec=$($LFS changelog $(facet_svc mds$i) |
12766                             awk '{ print $1; exit; }')
12767
12768                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
12769                 [ $((user_rec1 + 1)) == $first_rec ] ||
12770                         error "mds$i: first index should be $user_rec1 + 1, " \
12771                               "but is $first_rec"
12772         done
12773 }
12774 run_test 160f "changelog garbage collect (timestamped users)"
12775
12776 test_160g() {
12777         remote_mds_nodsh && skip "remote MDS with nodsh"
12778         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12779                 skip "Need MDS version at least 2.10.56"
12780
12781         local mdts=$(comma_list $(mdts_nodes))
12782
12783         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
12784         do_nodes $mdts $LCTL set_param fail_loc=0x1314
12785
12786         # Create a user
12787         changelog_register || error "first changelog_register failed"
12788         changelog_register || error "second changelog_register failed"
12789         local cl_users
12790         declare -A cl_user1
12791         declare -A cl_user2
12792         local user_rec1
12793         local user_rec2
12794         local i
12795
12796         # generate some changelog records to accumulate on each MDT
12797         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
12798         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12799                 error "create $DIR/$tdir/$tfile failed"
12800
12801         # check changelogs have been generated
12802         local nbcl=$(changelog_dump | wc -l)
12803         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12804
12805         # reduce the max_idle_indexes value to make sure we exceed it
12806         max_ndx=$((nbcl / 2 - 1))
12807
12808         for param in "changelog_max_idle_indexes=$max_ndx" \
12809                      "changelog_gc=1" \
12810                      "changelog_min_gc_interval=2" \
12811                      "changelog_min_free_cat_entries=3"; do
12812                 local MDT0=$(facet_svc $SINGLEMDS)
12813                 local var="${param%=*}"
12814                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12815
12816                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12817                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
12818                         error "unable to set mdd.*.$param"
12819         done
12820
12821         # simulate changelog catalog almost full
12822         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
12823         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
12824
12825         for i in $(seq $MDSCOUNT); do
12826                 cl_users=(${CL_USERS[mds$i]})
12827                 cl_user1[mds$i]="${cl_users[0]}"
12828                 cl_user2[mds$i]="${cl_users[1]}"
12829
12830                 [ -n "${cl_user1[mds$i]}" ] ||
12831                         error "mds$i: no user registered"
12832                 [ -n "${cl_user2[mds$i]}" ] ||
12833                         error "mds$i: only ${cl_user1[mds$i]} is registered"
12834
12835                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12836                 [ -n "$user_rec1" ] ||
12837                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12838                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12839                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12840                 [ -n "$user_rec2" ] ||
12841                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12842                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12843                      "$user_rec1 + 2 == $user_rec2"
12844                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12845                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12846                               "$user_rec1 + 2, but is $user_rec2"
12847                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12848                 [ -n "$user_rec2" ] ||
12849                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12850                 [ $user_rec1 == $user_rec2 ] ||
12851                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12852                               "$user_rec1, but is $user_rec2"
12853         done
12854
12855         # ensure we are past the previous changelog_min_gc_interval set above
12856         sleep 2
12857
12858         # generate one more changelog to trigger fail_loc
12859         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12860                 error "create $DIR/$tdir/${tfile}bis failed"
12861
12862         # ensure gc thread is done
12863         for i in $(mdts_nodes); do
12864                 wait_update $i \
12865                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
12866                         error "$i: GC-thread not done"
12867         done
12868
12869         local first_rec
12870         for i in $(seq $MDSCOUNT); do
12871                 # check cl_user1 still registered
12872                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
12873                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12874                 # check cl_user2 unregistered
12875                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
12876                         error "mds$i: User ${cl_user2[mds$i]} still registered"
12877
12878                 # check changelogs are present and starting at $user_rec1 + 1
12879                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12880                 [ -n "$user_rec1" ] ||
12881                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12882                 first_rec=$($LFS changelog $(facet_svc mds$i) |
12883                             awk '{ print $1; exit; }')
12884
12885                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
12886                 [ $((user_rec1 + 1)) == $first_rec ] ||
12887                         error "mds$i: first index should be $user_rec1 + 1, " \
12888                               "but is $first_rec"
12889         done
12890 }
12891 run_test 160g "changelog garbage collect (old users)"
12892
12893 test_160h() {
12894         remote_mds_nodsh && skip "remote MDS with nodsh" && return
12895         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12896                 skip "Need MDS version at least 2.10.56"
12897
12898         local mdts=$(comma_list $(mdts_nodes))
12899
12900         # Create a user
12901         changelog_register || error "first changelog_register failed"
12902         changelog_register || error "second changelog_register failed"
12903         local cl_users
12904         declare -A cl_user1
12905         declare -A cl_user2
12906         local user_rec1
12907         local user_rec2
12908         local i
12909
12910         # generate some changelog records to accumulate on each MDT
12911         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
12912         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12913                 error "create $DIR/$tdir/$tfile failed"
12914
12915         # check changelogs have been generated
12916         local nbcl=$(changelog_dump | wc -l)
12917         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12918
12919         for param in "changelog_max_idle_time=10" \
12920                      "changelog_gc=1" \
12921                      "changelog_min_gc_interval=2"; do
12922                 local MDT0=$(facet_svc $SINGLEMDS)
12923                 local var="${param%=*}"
12924                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12925
12926                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12927                 do_nodes $mdts $LCTL set_param mdd.*.$param
12928         done
12929
12930         # force cl_user2 to be idle (1st part)
12931         sleep 9
12932
12933         for i in $(seq $MDSCOUNT); do
12934                 cl_users=(${CL_USERS[mds$i]})
12935                 cl_user1[mds$i]="${cl_users[0]}"
12936                 cl_user2[mds$i]="${cl_users[1]}"
12937
12938                 [ -n "${cl_user1[mds$i]}" ] ||
12939                         error "mds$i: no user registered"
12940                 [ -n "${cl_user2[mds$i]}" ] ||
12941                         error "mds$i: only ${cl_user2[mds$i]} is registered"
12942
12943                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12944                 [ -n "$user_rec1" ] ||
12945                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12946                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12947                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12948                 [ -n "$user_rec2" ] ||
12949                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12950                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12951                      "$user_rec1 + 2 == $user_rec2"
12952                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12953                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12954                               "$user_rec1 + 2, but is $user_rec2"
12955                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12956                 [ -n "$user_rec2" ] ||
12957                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12958                 [ $user_rec1 == $user_rec2 ] ||
12959                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12960                               "$user_rec1, but is $user_rec2"
12961         done
12962
12963         # force cl_user2 to be idle (2nd part) and to reach
12964         # changelog_max_idle_time
12965         sleep 2
12966
12967         # force each GC-thread start and block then
12968         # one per MDT/MDD, set fail_val accordingly
12969         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
12970         do_nodes $mdts $LCTL set_param fail_loc=0x1316
12971
12972         # generate more changelogs to trigger fail_loc
12973         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12974                 error "create $DIR/$tdir/${tfile}bis failed"
12975
12976         # stop MDT to stop GC-thread, should be done in back-ground as it will
12977         # block waiting for the thread to be released and exit
12978         declare -A stop_pids
12979         for i in $(seq $MDSCOUNT); do
12980                 stop mds$i &
12981                 stop_pids[mds$i]=$!
12982         done
12983
12984         for i in $(mdts_nodes); do
12985                 local facet
12986                 local nb=0
12987                 local facets=$(facets_up_on_host $i)
12988
12989                 for facet in ${facets//,/ }; do
12990                         if [[ $facet == mds* ]]; then
12991                                 nb=$((nb + 1))
12992                         fi
12993                 done
12994                 # ensure each MDS's gc threads are still present and all in "R"
12995                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
12996                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
12997                         error "$i: expected $nb GC-thread"
12998                 wait_update $i \
12999                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
13000                         "R" 20 ||
13001                         error "$i: GC-thread not found in R-state"
13002                 # check umounts of each MDT on MDS have reached kthread_stop()
13003                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
13004                         error "$i: expected $nb umount"
13005                 wait_update $i \
13006                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
13007                         error "$i: umount not found in D-state"
13008         done
13009
13010         # release all GC-threads
13011         do_nodes $mdts $LCTL set_param fail_loc=0
13012
13013         # wait for MDT stop to complete
13014         for i in $(seq $MDSCOUNT); do
13015                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
13016         done
13017
13018         # XXX
13019         # may try to check if any orphan changelog records are present
13020         # via ldiskfs/zfs and llog_reader...
13021
13022         # re-start/mount MDTs
13023         for i in $(seq $MDSCOUNT); do
13024                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
13025                         error "Fail to start mds$i"
13026         done
13027
13028         local first_rec
13029         for i in $(seq $MDSCOUNT); do
13030                 # check cl_user1 still registered
13031                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13032                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13033                 # check cl_user2 unregistered
13034                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13035                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13036
13037                 # check changelogs are present and starting at $user_rec1 + 1
13038                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13039                 [ -n "$user_rec1" ] ||
13040                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13041                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13042                             awk '{ print $1; exit; }')
13043
13044                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13045                 [ $((user_rec1 + 1)) == $first_rec ] ||
13046                         error "mds$i: first index should be $user_rec1 + 1, " \
13047                               "but is $first_rec"
13048         done
13049 }
13050 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
13051               "during mount"
13052
13053 test_160i() {
13054
13055         local mdts=$(comma_list $(mdts_nodes))
13056
13057         changelog_register || error "first changelog_register failed"
13058
13059         # generate some changelog records to accumulate on each MDT
13060         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13061         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13062                 error "create $DIR/$tdir/$tfile failed"
13063
13064         # check changelogs have been generated
13065         local nbcl=$(changelog_dump | wc -l)
13066         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13067
13068         # simulate race between register and unregister
13069         # XXX as fail_loc is set per-MDS, with DNE configs the race
13070         # simulation will only occur for one MDT per MDS and for the
13071         # others the normal race scenario will take place
13072         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
13073         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
13074         do_nodes $mdts $LCTL set_param fail_val=1
13075
13076         # unregister 1st user
13077         changelog_deregister &
13078         local pid1=$!
13079         # wait some time for deregister work to reach race rdv
13080         sleep 2
13081         # register 2nd user
13082         changelog_register || error "2nd user register failed"
13083
13084         wait $pid1 || error "1st user deregister failed"
13085
13086         local i
13087         local last_rec
13088         declare -A LAST_REC
13089         for i in $(seq $MDSCOUNT); do
13090                 if changelog_users mds$i | grep "^cl"; then
13091                         # make sure new records are added with one user present
13092                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
13093                                           awk '/^current.index:/ { print $NF }')
13094                 else
13095                         error "mds$i has no user registered"
13096                 fi
13097         done
13098
13099         # generate more changelog records to accumulate on each MDT
13100         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13101                 error "create $DIR/$tdir/${tfile}bis failed"
13102
13103         for i in $(seq $MDSCOUNT); do
13104                 last_rec=$(changelog_users $SINGLEMDS |
13105                            awk '/^current.index:/ { print $NF }')
13106                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
13107                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
13108                         error "changelogs are off on mds$i"
13109         done
13110 }
13111 run_test 160i "changelog user register/unregister race"
13112
13113 test_161a() {
13114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13115
13116         test_mkdir -c1 $DIR/$tdir
13117         cp /etc/hosts $DIR/$tdir/$tfile
13118         test_mkdir -c1 $DIR/$tdir/foo1
13119         test_mkdir -c1 $DIR/$tdir/foo2
13120         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
13121         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
13122         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
13123         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
13124         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
13125         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13126                 $LFS fid2path $DIR $FID
13127                 error "bad link ea"
13128         fi
13129         # middle
13130         rm $DIR/$tdir/foo2/zachary
13131         # last
13132         rm $DIR/$tdir/foo2/thor
13133         # first
13134         rm $DIR/$tdir/$tfile
13135         # rename
13136         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
13137         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
13138                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
13139         rm $DIR/$tdir/foo2/maggie
13140
13141         # overflow the EA
13142         local longname=$tfile.avg_len_is_thirty_two_
13143         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
13144                 error_noexit 'failed to unlink many hardlinks'" EXIT
13145         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
13146                 error "failed to hardlink many files"
13147         links=$($LFS fid2path $DIR $FID | wc -l)
13148         echo -n "${links}/1000 links in link EA"
13149         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
13150 }
13151 run_test 161a "link ea sanity"
13152
13153 test_161b() {
13154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13155         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
13156
13157         local MDTIDX=1
13158         local remote_dir=$DIR/$tdir/remote_dir
13159
13160         mkdir -p $DIR/$tdir
13161         $LFS mkdir -i $MDTIDX $remote_dir ||
13162                 error "create remote directory failed"
13163
13164         cp /etc/hosts $remote_dir/$tfile
13165         mkdir -p $remote_dir/foo1
13166         mkdir -p $remote_dir/foo2
13167         ln $remote_dir/$tfile $remote_dir/foo1/sofia
13168         ln $remote_dir/$tfile $remote_dir/foo2/zachary
13169         ln $remote_dir/$tfile $remote_dir/foo1/luna
13170         ln $remote_dir/$tfile $remote_dir/foo2/thor
13171
13172         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
13173                      tr -d ']')
13174         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13175                 $LFS fid2path $DIR $FID
13176                 error "bad link ea"
13177         fi
13178         # middle
13179         rm $remote_dir/foo2/zachary
13180         # last
13181         rm $remote_dir/foo2/thor
13182         # first
13183         rm $remote_dir/$tfile
13184         # rename
13185         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
13186         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
13187         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
13188                 $LFS fid2path $DIR $FID
13189                 error "bad link rename"
13190         fi
13191         rm $remote_dir/foo2/maggie
13192
13193         # overflow the EA
13194         local longname=filename_avg_len_is_thirty_two_
13195         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
13196                 error "failed to hardlink many files"
13197         links=$($LFS fid2path $DIR $FID | wc -l)
13198         echo -n "${links}/1000 links in link EA"
13199         [[ ${links} -gt 60 ]] ||
13200                 error "expected at least 60 links in link EA"
13201         unlinkmany $remote_dir/foo2/$longname 1000 ||
13202         error "failed to unlink many hardlinks"
13203 }
13204 run_test 161b "link ea sanity under remote directory"
13205
13206 test_161c() {
13207         remote_mds_nodsh && skip "remote MDS with nodsh"
13208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13209         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
13210                 skip "Need MDS version at least 2.1.5"
13211
13212         # define CLF_RENAME_LAST 0x0001
13213         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
13214         changelog_register || error "changelog_register failed"
13215
13216         rm -rf $DIR/$tdir
13217         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
13218         touch $DIR/$tdir/foo_161c
13219         touch $DIR/$tdir/bar_161c
13220         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13221         changelog_dump | grep RENME | tail -n 5
13222         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13223         changelog_clear 0 || error "changelog_clear failed"
13224         if [ x$flags != "x0x1" ]; then
13225                 error "flag $flags is not 0x1"
13226         fi
13227
13228         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
13229         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
13230         touch $DIR/$tdir/foo_161c
13231         touch $DIR/$tdir/bar_161c
13232         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13233         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13234         changelog_dump | grep RENME | tail -n 5
13235         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13236         changelog_clear 0 || error "changelog_clear failed"
13237         if [ x$flags != "x0x0" ]; then
13238                 error "flag $flags is not 0x0"
13239         fi
13240         echo "rename overwrite a target having nlink > 1," \
13241                 "changelog record has flags of $flags"
13242
13243         # rename doesn't overwrite a target (changelog flag 0x0)
13244         touch $DIR/$tdir/foo_161c
13245         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
13246         changelog_dump | grep RENME | tail -n 5
13247         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
13248         changelog_clear 0 || error "changelog_clear failed"
13249         if [ x$flags != "x0x0" ]; then
13250                 error "flag $flags is not 0x0"
13251         fi
13252         echo "rename doesn't overwrite a target," \
13253                 "changelog record has flags of $flags"
13254
13255         # define CLF_UNLINK_LAST 0x0001
13256         # unlink a file having nlink = 1 (changelog flag 0x1)
13257         rm -f $DIR/$tdir/foo2_161c
13258         changelog_dump | grep UNLNK | tail -n 5
13259         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13260         changelog_clear 0 || error "changelog_clear failed"
13261         if [ x$flags != "x0x1" ]; then
13262                 error "flag $flags is not 0x1"
13263         fi
13264         echo "unlink a file having nlink = 1," \
13265                 "changelog record has flags of $flags"
13266
13267         # unlink a file having nlink > 1 (changelog flag 0x0)
13268         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13269         rm -f $DIR/$tdir/foobar_161c
13270         changelog_dump | grep UNLNK | tail -n 5
13271         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13272         changelog_clear 0 || error "changelog_clear failed"
13273         if [ x$flags != "x0x0" ]; then
13274                 error "flag $flags is not 0x0"
13275         fi
13276         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
13277 }
13278 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
13279
13280 test_161d() {
13281         remote_mds_nodsh && skip "remote MDS with nodsh"
13282         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
13283
13284         local pid
13285         local fid
13286
13287         changelog_register || error "changelog_register failed"
13288
13289         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
13290         # interfer with $MOUNT/.lustre/fid/ access
13291         mkdir $DIR/$tdir
13292         [[ $? -eq 0 ]] || error "mkdir failed"
13293
13294         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
13295         $LCTL set_param fail_loc=0x8000140c
13296         # 5s pause
13297         $LCTL set_param fail_val=5
13298
13299         # create file
13300         echo foofoo > $DIR/$tdir/$tfile &
13301         pid=$!
13302
13303         # wait for create to be delayed
13304         sleep 2
13305
13306         ps -p $pid
13307         [[ $? -eq 0 ]] || error "create should be blocked"
13308
13309         local tempfile=$(mktemp)
13310         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
13311         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
13312         # some delay may occur during ChangeLog publishing and file read just
13313         # above, that could allow file write to happen finally
13314         [[ -s $tempfile ]] && echo "file should be empty"
13315
13316         $LCTL set_param fail_loc=0
13317
13318         wait $pid
13319         [[ $? -eq 0 ]] || error "create failed"
13320 }
13321 run_test 161d "create with concurrent .lustre/fid access"
13322
13323 check_path() {
13324         local expected="$1"
13325         shift
13326         local fid="$2"
13327
13328         local path
13329         path=$($LFS fid2path "$@")
13330         local rc=$?
13331
13332         if [ $rc -ne 0 ]; then
13333                 error "path looked up of '$expected' failed: rc=$rc"
13334         elif [ "$path" != "$expected" ]; then
13335                 error "path looked up '$path' instead of '$expected'"
13336         else
13337                 echo "FID '$fid' resolves to path '$path' as expected"
13338         fi
13339 }
13340
13341 test_162a() { # was test_162
13342         test_mkdir -p -c1 $DIR/$tdir/d2
13343         touch $DIR/$tdir/d2/$tfile
13344         touch $DIR/$tdir/d2/x1
13345         touch $DIR/$tdir/d2/x2
13346         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
13347         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
13348         # regular file
13349         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
13350         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
13351
13352         # softlink
13353         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
13354         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
13355         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
13356
13357         # softlink to wrong file
13358         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
13359         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
13360         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
13361
13362         # hardlink
13363         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
13364         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
13365         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
13366         # fid2path dir/fsname should both work
13367         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
13368         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
13369
13370         # hardlink count: check that there are 2 links
13371         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
13372         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
13373
13374         # hardlink indexing: remove the first link
13375         rm $DIR/$tdir/d2/p/q/r/hlink
13376         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
13377 }
13378 run_test 162a "path lookup sanity"
13379
13380 test_162b() {
13381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13382         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13383
13384         mkdir $DIR/$tdir
13385         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
13386                                 error "create striped dir failed"
13387
13388         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
13389                                         tail -n 1 | awk '{print $2}')
13390         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
13391
13392         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
13393         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
13394
13395         # regular file
13396         for ((i=0;i<5;i++)); do
13397                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
13398                         error "get fid for f$i failed"
13399                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
13400
13401                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
13402                         error "get fid for d$i failed"
13403                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
13404         done
13405
13406         return 0
13407 }
13408 run_test 162b "striped directory path lookup sanity"
13409
13410 # LU-4239: Verify fid2path works with paths 100 or more directories deep
13411 test_162c() {
13412         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
13413                 skip "Need MDS version at least 2.7.51"
13414
13415         local lpath=$tdir.local
13416         local rpath=$tdir.remote
13417
13418         test_mkdir $DIR/$lpath
13419         test_mkdir $DIR/$rpath
13420
13421         for ((i = 0; i <= 101; i++)); do
13422                 lpath="$lpath/$i"
13423                 mkdir $DIR/$lpath
13424                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
13425                         error "get fid for local directory $DIR/$lpath failed"
13426                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
13427
13428                 rpath="$rpath/$i"
13429                 test_mkdir $DIR/$rpath
13430                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
13431                         error "get fid for remote directory $DIR/$rpath failed"
13432                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
13433         done
13434
13435         return 0
13436 }
13437 run_test 162c "fid2path works with paths 100 or more directories deep"
13438
13439 test_169() {
13440         # do directio so as not to populate the page cache
13441         log "creating a 10 Mb file"
13442         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
13443         log "starting reads"
13444         dd if=$DIR/$tfile of=/dev/null bs=4096 &
13445         log "truncating the file"
13446         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
13447         log "killing dd"
13448         kill %+ || true # reads might have finished
13449         echo "wait until dd is finished"
13450         wait
13451         log "removing the temporary file"
13452         rm -rf $DIR/$tfile || error "tmp file removal failed"
13453 }
13454 run_test 169 "parallel read and truncate should not deadlock"
13455
13456 test_170() {
13457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13458
13459         $LCTL clear     # bug 18514
13460         $LCTL debug_daemon start $TMP/${tfile}_log_good
13461         touch $DIR/$tfile
13462         $LCTL debug_daemon stop
13463         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
13464                 error "sed failed to read log_good"
13465
13466         $LCTL debug_daemon start $TMP/${tfile}_log_good
13467         rm -rf $DIR/$tfile
13468         $LCTL debug_daemon stop
13469
13470         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
13471                error "lctl df log_bad failed"
13472
13473         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13474         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13475
13476         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
13477         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
13478
13479         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
13480                 error "bad_line good_line1 good_line2 are empty"
13481
13482         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13483         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
13484         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13485
13486         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
13487         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13488         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13489
13490         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
13491                 error "bad_line_new good_line_new are empty"
13492
13493         local expected_good=$((good_line1 + good_line2*2))
13494
13495         rm -f $TMP/${tfile}*
13496         # LU-231, short malformed line may not be counted into bad lines
13497         if [ $bad_line -ne $bad_line_new ] &&
13498                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
13499                 error "expected $bad_line bad lines, but got $bad_line_new"
13500                 return 1
13501         fi
13502
13503         if [ $expected_good -ne $good_line_new ]; then
13504                 error "expected $expected_good good lines, but got $good_line_new"
13505                 return 2
13506         fi
13507         true
13508 }
13509 run_test 170 "test lctl df to handle corrupted log ====================="
13510
13511 test_171() { # bug20592
13512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13513
13514         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
13515         $LCTL set_param fail_loc=0x50e
13516         $LCTL set_param fail_val=3000
13517         multiop_bg_pause $DIR/$tfile O_s || true
13518         local MULTIPID=$!
13519         kill -USR1 $MULTIPID
13520         # cause log dump
13521         sleep 3
13522         wait $MULTIPID
13523         if dmesg | grep "recursive fault"; then
13524                 error "caught a recursive fault"
13525         fi
13526         $LCTL set_param fail_loc=0
13527         true
13528 }
13529 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
13530
13531 # it would be good to share it with obdfilter-survey/iokit-libecho code
13532 setup_obdecho_osc () {
13533         local rc=0
13534         local ost_nid=$1
13535         local obdfilter_name=$2
13536         echo "Creating new osc for $obdfilter_name on $ost_nid"
13537         # make sure we can find loopback nid
13538         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
13539
13540         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
13541                            ${obdfilter_name}_osc_UUID || rc=2; }
13542         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
13543                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
13544         return $rc
13545 }
13546
13547 cleanup_obdecho_osc () {
13548         local obdfilter_name=$1
13549         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
13550         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
13551         return 0
13552 }
13553
13554 obdecho_test() {
13555         local OBD=$1
13556         local node=$2
13557         local pages=${3:-64}
13558         local rc=0
13559         local id
13560
13561         local count=10
13562         local obd_size=$(get_obd_size $node $OBD)
13563         local page_size=$(get_page_size $node)
13564         if [[ -n "$obd_size" ]]; then
13565                 local new_count=$((obd_size / (pages * page_size / 1024)))
13566                 [[ $new_count -ge $count ]] || count=$new_count
13567         fi
13568
13569         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
13570         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
13571                            rc=2; }
13572         if [ $rc -eq 0 ]; then
13573             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
13574             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
13575         fi
13576         echo "New object id is $id"
13577         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
13578                            rc=4; }
13579         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
13580                            "test_brw $count w v $pages $id" || rc=4; }
13581         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
13582                            rc=4; }
13583         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
13584                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
13585         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
13586                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
13587         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
13588         return $rc
13589 }
13590
13591 test_180a() {
13592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13593
13594         if ! module_loaded obdecho; then
13595                 load_module obdecho/obdecho &&
13596                         stack_trap "rmmod obdecho" EXIT ||
13597                         error "unable to load obdecho on client"
13598         fi
13599
13600         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
13601         local host=$($LCTL get_param -n osc.$osc.import |
13602                      awk '/current_connection:/ { print $2 }' )
13603         local target=$($LCTL get_param -n osc.$osc.import |
13604                        awk '/target:/ { print $2 }' )
13605         target=${target%_UUID}
13606
13607         if [ -n "$target" ]; then
13608                 setup_obdecho_osc $host $target &&
13609                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
13610                         { error "obdecho setup failed with $?"; return; }
13611
13612                 obdecho_test ${target}_osc client ||
13613                         error "obdecho_test failed on ${target}_osc"
13614         else
13615                 $LCTL get_param osc.$osc.import
13616                 error "there is no osc.$osc.import target"
13617         fi
13618 }
13619 run_test 180a "test obdecho on osc"
13620
13621 test_180b() {
13622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13623         remote_ost_nodsh && skip "remote OST with nodsh"
13624
13625         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
13626                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
13627                 error "failed to load module obdecho"
13628
13629         local target=$(do_facet ost1 $LCTL dl |
13630                        awk '/obdfilter/ { print $4; exit; }')
13631
13632         if [ -n "$target" ]; then
13633                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
13634         else
13635                 do_facet ost1 $LCTL dl
13636                 error "there is no obdfilter target on ost1"
13637         fi
13638 }
13639 run_test 180b "test obdecho directly on obdfilter"
13640
13641 test_180c() { # LU-2598
13642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13643         remote_ost_nodsh && skip "remote OST with nodsh"
13644         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
13645                 skip "Need MDS version at least 2.4.0"
13646
13647         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
13648                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
13649                 error "failed to load module obdecho"
13650
13651         local target=$(do_facet ost1 $LCTL dl |
13652                        awk '/obdfilter/ { print $4; exit; }')
13653
13654         if [ -n "$target" ]; then
13655                 local pages=16384 # 64MB bulk I/O RPC size
13656
13657                 obdecho_test "$target" ost1 "$pages" ||
13658                         error "obdecho_test with pages=$pages failed with $?"
13659         else
13660                 do_facet ost1 $LCTL dl
13661                 error "there is no obdfilter target on ost1"
13662         fi
13663 }
13664 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
13665
13666 test_181() { # bug 22177
13667         test_mkdir $DIR/$tdir
13668         # create enough files to index the directory
13669         createmany -o $DIR/$tdir/foobar 4000
13670         # print attributes for debug purpose
13671         lsattr -d .
13672         # open dir
13673         multiop_bg_pause $DIR/$tdir D_Sc || return 1
13674         MULTIPID=$!
13675         # remove the files & current working dir
13676         unlinkmany $DIR/$tdir/foobar 4000
13677         rmdir $DIR/$tdir
13678         kill -USR1 $MULTIPID
13679         wait $MULTIPID
13680         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
13681         return 0
13682 }
13683 run_test 181 "Test open-unlinked dir ========================"
13684
13685 test_182() {
13686         local fcount=1000
13687         local tcount=10
13688
13689         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13690
13691         $LCTL set_param mdc.*.rpc_stats=clear
13692
13693         for (( i = 0; i < $tcount; i++ )) ; do
13694                 mkdir $DIR/$tdir/$i
13695         done
13696
13697         for (( i = 0; i < $tcount; i++ )) ; do
13698                 createmany -o $DIR/$tdir/$i/f- $fcount &
13699         done
13700         wait
13701
13702         for (( i = 0; i < $tcount; i++ )) ; do
13703                 unlinkmany $DIR/$tdir/$i/f- $fcount &
13704         done
13705         wait
13706
13707         $LCTL get_param mdc.*.rpc_stats
13708
13709         rm -rf $DIR/$tdir
13710 }
13711 run_test 182 "Test parallel modify metadata operations ================"
13712
13713 test_183() { # LU-2275
13714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13715         remote_mds_nodsh && skip "remote MDS with nodsh"
13716         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
13717                 skip "Need MDS version at least 2.3.56"
13718
13719         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13720         echo aaa > $DIR/$tdir/$tfile
13721
13722 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
13723         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
13724
13725         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
13726         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
13727
13728         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
13729
13730         # Flush negative dentry cache
13731         touch $DIR/$tdir/$tfile
13732
13733         # We are not checking for any leaked references here, they'll
13734         # become evident next time we do cleanup with module unload.
13735         rm -rf $DIR/$tdir
13736 }
13737 run_test 183 "No crash or request leak in case of strange dispositions ========"
13738
13739 # test suite 184 is for LU-2016, LU-2017
13740 test_184a() {
13741         check_swap_layouts_support
13742
13743         dir0=$DIR/$tdir/$testnum
13744         test_mkdir -p -c1 $dir0
13745         ref1=/etc/passwd
13746         ref2=/etc/group
13747         file1=$dir0/f1
13748         file2=$dir0/f2
13749         $LFS setstripe -c1 $file1
13750         cp $ref1 $file1
13751         $LFS setstripe -c2 $file2
13752         cp $ref2 $file2
13753         gen1=$($LFS getstripe -g $file1)
13754         gen2=$($LFS getstripe -g $file2)
13755
13756         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
13757         gen=$($LFS getstripe -g $file1)
13758         [[ $gen1 != $gen ]] ||
13759                 "Layout generation on $file1 does not change"
13760         gen=$($LFS getstripe -g $file2)
13761         [[ $gen2 != $gen ]] ||
13762                 "Layout generation on $file2 does not change"
13763
13764         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
13765         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
13766
13767         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
13768 }
13769 run_test 184a "Basic layout swap"
13770
13771 test_184b() {
13772         check_swap_layouts_support
13773
13774         dir0=$DIR/$tdir/$testnum
13775         mkdir -p $dir0 || error "creating dir $dir0"
13776         file1=$dir0/f1
13777         file2=$dir0/f2
13778         file3=$dir0/f3
13779         dir1=$dir0/d1
13780         dir2=$dir0/d2
13781         mkdir $dir1 $dir2
13782         $LFS setstripe -c1 $file1
13783         $LFS setstripe -c2 $file2
13784         $LFS setstripe -c1 $file3
13785         chown $RUNAS_ID $file3
13786         gen1=$($LFS getstripe -g $file1)
13787         gen2=$($LFS getstripe -g $file2)
13788
13789         $LFS swap_layouts $dir1 $dir2 &&
13790                 error "swap of directories layouts should fail"
13791         $LFS swap_layouts $dir1 $file1 &&
13792                 error "swap of directory and file layouts should fail"
13793         $RUNAS $LFS swap_layouts $file1 $file2 &&
13794                 error "swap of file we cannot write should fail"
13795         $LFS swap_layouts $file1 $file3 &&
13796                 error "swap of file with different owner should fail"
13797         /bin/true # to clear error code
13798 }
13799 run_test 184b "Forbidden layout swap (will generate errors)"
13800
13801 test_184c() {
13802         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
13803         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
13804         check_swap_layouts_support
13805
13806         local dir0=$DIR/$tdir/$testnum
13807         mkdir -p $dir0 || error "creating dir $dir0"
13808
13809         local ref1=$dir0/ref1
13810         local ref2=$dir0/ref2
13811         local file1=$dir0/file1
13812         local file2=$dir0/file2
13813         # create a file large enough for the concurrent test
13814         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
13815         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
13816         echo "ref file size: ref1($(stat -c %s $ref1))," \
13817              "ref2($(stat -c %s $ref2))"
13818
13819         cp $ref2 $file2
13820         dd if=$ref1 of=$file1 bs=16k &
13821         local DD_PID=$!
13822
13823         # Make sure dd starts to copy file
13824         while [ ! -f $file1 ]; do sleep 0.1; done
13825
13826         $LFS swap_layouts $file1 $file2
13827         local rc=$?
13828         wait $DD_PID
13829         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
13830         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
13831
13832         # how many bytes copied before swapping layout
13833         local copied=$(stat -c %s $file2)
13834         local remaining=$(stat -c %s $ref1)
13835         remaining=$((remaining - copied))
13836         echo "Copied $copied bytes before swapping layout..."
13837
13838         cmp -n $copied $file1 $ref2 | grep differ &&
13839                 error "Content mismatch [0, $copied) of ref2 and file1"
13840         cmp -n $copied $file2 $ref1 ||
13841                 error "Content mismatch [0, $copied) of ref1 and file2"
13842         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
13843                 error "Content mismatch [$copied, EOF) of ref1 and file1"
13844
13845         # clean up
13846         rm -f $ref1 $ref2 $file1 $file2
13847 }
13848 run_test 184c "Concurrent write and layout swap"
13849
13850 test_184d() {
13851         check_swap_layouts_support
13852         [ -z "$(which getfattr 2>/dev/null)" ] &&
13853                 skip_env "no getfattr command"
13854
13855         local file1=$DIR/$tdir/$tfile-1
13856         local file2=$DIR/$tdir/$tfile-2
13857         local file3=$DIR/$tdir/$tfile-3
13858         local lovea1
13859         local lovea2
13860
13861         mkdir -p $DIR/$tdir
13862         touch $file1 || error "create $file1 failed"
13863         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
13864                 error "create $file2 failed"
13865         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
13866                 error "create $file3 failed"
13867         lovea1=$(get_layout_param $file1)
13868
13869         $LFS swap_layouts $file2 $file3 ||
13870                 error "swap $file2 $file3 layouts failed"
13871         $LFS swap_layouts $file1 $file2 ||
13872                 error "swap $file1 $file2 layouts failed"
13873
13874         lovea2=$(get_layout_param $file2)
13875         echo "$lovea1"
13876         echo "$lovea2"
13877         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
13878
13879         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
13880         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
13881 }
13882 run_test 184d "allow stripeless layouts swap"
13883
13884 test_184e() {
13885         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
13886                 skip "Need MDS version at least 2.6.94"
13887         check_swap_layouts_support
13888         [ -z "$(which getfattr 2>/dev/null)" ] &&
13889                 skip_env "no getfattr command"
13890
13891         local file1=$DIR/$tdir/$tfile-1
13892         local file2=$DIR/$tdir/$tfile-2
13893         local file3=$DIR/$tdir/$tfile-3
13894         local lovea
13895
13896         mkdir -p $DIR/$tdir
13897         touch $file1 || error "create $file1 failed"
13898         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
13899                 error "create $file2 failed"
13900         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
13901                 error "create $file3 failed"
13902
13903         $LFS swap_layouts $file1 $file2 ||
13904                 error "swap $file1 $file2 layouts failed"
13905
13906         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
13907         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
13908
13909         echo 123 > $file1 || error "Should be able to write into $file1"
13910
13911         $LFS swap_layouts $file1 $file3 ||
13912                 error "swap $file1 $file3 layouts failed"
13913
13914         echo 123 > $file1 || error "Should be able to write into $file1"
13915
13916         rm -rf $file1 $file2 $file3
13917 }
13918 run_test 184e "Recreate layout after stripeless layout swaps"
13919
13920 test_184f() {
13921         # Create a file with name longer than sizeof(struct stat) ==
13922         # 144 to see if we can get chars from the file name to appear
13923         # in the returned striping. Note that 'f' == 0x66.
13924         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
13925
13926         mkdir -p $DIR/$tdir
13927         mcreate $DIR/$tdir/$file
13928         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
13929                 error "IOC_MDC_GETFILEINFO returned garbage striping"
13930         fi
13931 }
13932 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
13933
13934 test_185() { # LU-2441
13935         # LU-3553 - no volatile file support in old servers
13936         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
13937                 skip "Need MDS version at least 2.3.60"
13938
13939         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13940         touch $DIR/$tdir/spoo
13941         local mtime1=$(stat -c "%Y" $DIR/$tdir)
13942         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
13943                 error "cannot create/write a volatile file"
13944         [ "$FILESET" == "" ] &&
13945         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
13946                 error "FID is still valid after close"
13947
13948         multiop_bg_pause $DIR/$tdir vVw4096_c
13949         local multi_pid=$!
13950
13951         local OLD_IFS=$IFS
13952         IFS=":"
13953         local fidv=($fid)
13954         IFS=$OLD_IFS
13955         # assume that the next FID for this client is sequential, since stdout
13956         # is unfortunately eaten by multiop_bg_pause
13957         local n=$((${fidv[1]} + 1))
13958         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
13959         if [ "$FILESET" == "" ]; then
13960                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
13961                         error "FID is missing before close"
13962         fi
13963         kill -USR1 $multi_pid
13964         # 1 second delay, so if mtime change we will see it
13965         sleep 1
13966         local mtime2=$(stat -c "%Y" $DIR/$tdir)
13967         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
13968 }
13969 run_test 185 "Volatile file support"
13970
13971 test_187a() {
13972         remote_mds_nodsh && skip "remote MDS with nodsh"
13973         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
13974                 skip "Need MDS version at least 2.3.0"
13975
13976         local dir0=$DIR/$tdir/$testnum
13977         mkdir -p $dir0 || error "creating dir $dir0"
13978
13979         local file=$dir0/file1
13980         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
13981         local dv1=$($LFS data_version $file)
13982         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
13983         local dv2=$($LFS data_version $file)
13984         [[ $dv1 != $dv2 ]] ||
13985                 error "data version did not change on write $dv1 == $dv2"
13986
13987         # clean up
13988         rm -f $file1
13989 }
13990 run_test 187a "Test data version change"
13991
13992 test_187b() {
13993         remote_mds_nodsh && skip "remote MDS with nodsh"
13994         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
13995                 skip "Need MDS version at least 2.3.0"
13996
13997         local dir0=$DIR/$tdir/$testnum
13998         mkdir -p $dir0 || error "creating dir $dir0"
13999
14000         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
14001         [[ ${DV[0]} != ${DV[1]} ]] ||
14002                 error "data version did not change on write"\
14003                       " ${DV[0]} == ${DV[1]}"
14004
14005         # clean up
14006         rm -f $file1
14007 }
14008 run_test 187b "Test data version change on volatile file"
14009
14010 test_200() {
14011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14012         remote_mgs_nodsh && skip "remote MGS with nodsh"
14013         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14014
14015         local POOL=${POOL:-cea1}
14016         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
14017         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
14018         # Pool OST targets
14019         local first_ost=0
14020         local last_ost=$(($OSTCOUNT - 1))
14021         local ost_step=2
14022         local ost_list=$(seq $first_ost $ost_step $last_ost)
14023         local ost_range="$first_ost $last_ost $ost_step"
14024         local test_path=$POOL_ROOT/$POOL_DIR_NAME
14025         local file_dir=$POOL_ROOT/file_tst
14026         local subdir=$test_path/subdir
14027         local rc=0
14028
14029         if ! combined_mgs_mds ; then
14030                 mount_mgs_client
14031         fi
14032
14033         while : ; do
14034                 # former test_200a test_200b
14035                 pool_add $POOL                          || { rc=$? ; break; }
14036                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
14037                 # former test_200c test_200d
14038                 mkdir -p $test_path
14039                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
14040                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
14041                 mkdir -p $subdir
14042                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
14043                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
14044                                                         || { rc=$? ; break; }
14045                 # former test_200e test_200f
14046                 local files=$((OSTCOUNT*3))
14047                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
14048                                                         || { rc=$? ; break; }
14049                 pool_create_files $POOL $file_dir $files "$ost_list" \
14050                                                         || { rc=$? ; break; }
14051                 # former test_200g test_200h
14052                 pool_lfs_df $POOL                       || { rc=$? ; break; }
14053                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
14054
14055                 # former test_201a test_201b test_201c
14056                 pool_remove_first_target $POOL          || { rc=$? ; break; }
14057
14058                 local f=$test_path/$tfile
14059                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
14060                 pool_remove $POOL $f                    || { rc=$? ; break; }
14061                 break
14062         done
14063
14064         destroy_test_pools
14065
14066         if ! combined_mgs_mds ; then
14067                 umount_mgs_client
14068         fi
14069         return $rc
14070 }
14071 run_test 200 "OST pools"
14072
14073 # usage: default_attr <count | size | offset>
14074 default_attr() {
14075         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
14076 }
14077
14078 # usage: check_default_stripe_attr
14079 check_default_stripe_attr() {
14080         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
14081         case $1 in
14082         --stripe-count|-c)
14083                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
14084         --stripe-size|-S)
14085                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
14086         --stripe-index|-i)
14087                 EXPECTED=-1;;
14088         *)
14089                 error "unknown getstripe attr '$1'"
14090         esac
14091
14092         [ $ACTUAL == $EXPECTED ] ||
14093                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
14094 }
14095
14096 test_204a() {
14097         test_mkdir $DIR/$tdir
14098         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
14099
14100         check_default_stripe_attr --stripe-count
14101         check_default_stripe_attr --stripe-size
14102         check_default_stripe_attr --stripe-index
14103 }
14104 run_test 204a "Print default stripe attributes"
14105
14106 test_204b() {
14107         test_mkdir $DIR/$tdir
14108         $LFS setstripe --stripe-count 1 $DIR/$tdir
14109
14110         check_default_stripe_attr --stripe-size
14111         check_default_stripe_attr --stripe-index
14112 }
14113 run_test 204b "Print default stripe size and offset"
14114
14115 test_204c() {
14116         test_mkdir $DIR/$tdir
14117         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14118
14119         check_default_stripe_attr --stripe-count
14120         check_default_stripe_attr --stripe-index
14121 }
14122 run_test 204c "Print default stripe count and offset"
14123
14124 test_204d() {
14125         test_mkdir $DIR/$tdir
14126         $LFS setstripe --stripe-index 0 $DIR/$tdir
14127
14128         check_default_stripe_attr --stripe-count
14129         check_default_stripe_attr --stripe-size
14130 }
14131 run_test 204d "Print default stripe count and size"
14132
14133 test_204e() {
14134         test_mkdir $DIR/$tdir
14135         $LFS setstripe -d $DIR/$tdir
14136
14137         check_default_stripe_attr --stripe-count --raw
14138         check_default_stripe_attr --stripe-size --raw
14139         check_default_stripe_attr --stripe-index --raw
14140 }
14141 run_test 204e "Print raw stripe attributes"
14142
14143 test_204f() {
14144         test_mkdir $DIR/$tdir
14145         $LFS setstripe --stripe-count 1 $DIR/$tdir
14146
14147         check_default_stripe_attr --stripe-size --raw
14148         check_default_stripe_attr --stripe-index --raw
14149 }
14150 run_test 204f "Print raw stripe size and offset"
14151
14152 test_204g() {
14153         test_mkdir $DIR/$tdir
14154         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14155
14156         check_default_stripe_attr --stripe-count --raw
14157         check_default_stripe_attr --stripe-index --raw
14158 }
14159 run_test 204g "Print raw stripe count and offset"
14160
14161 test_204h() {
14162         test_mkdir $DIR/$tdir
14163         $LFS setstripe --stripe-index 0 $DIR/$tdir
14164
14165         check_default_stripe_attr --stripe-count --raw
14166         check_default_stripe_attr --stripe-size --raw
14167 }
14168 run_test 204h "Print raw stripe count and size"
14169
14170 # Figure out which job scheduler is being used, if any,
14171 # or use a fake one
14172 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
14173         JOBENV=SLURM_JOB_ID
14174 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
14175         JOBENV=LSB_JOBID
14176 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
14177         JOBENV=PBS_JOBID
14178 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
14179         JOBENV=LOADL_STEP_ID
14180 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
14181         JOBENV=JOB_ID
14182 else
14183         $LCTL list_param jobid_name > /dev/null 2>&1
14184         if [ $? -eq 0 ]; then
14185                 JOBENV=nodelocal
14186         else
14187                 JOBENV=FAKE_JOBID
14188         fi
14189 fi
14190 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
14191
14192 verify_jobstats() {
14193         local cmd=($1)
14194         shift
14195         local facets="$@"
14196
14197 # we don't really need to clear the stats for this test to work, since each
14198 # command has a unique jobid, but it makes debugging easier if needed.
14199 #       for facet in $facets; do
14200 #               local dev=$(convert_facet2label $facet)
14201 #               # clear old jobstats
14202 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
14203 #       done
14204
14205         # use a new JobID for each test, or we might see an old one
14206         [ "$JOBENV" = "FAKE_JOBID" ] &&
14207                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
14208
14209         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
14210
14211         [ "$JOBENV" = "nodelocal" ] && {
14212                 FAKE_JOBID=id.$testnum.%e.$RANDOM
14213                 $LCTL set_param jobid_name=$FAKE_JOBID
14214                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
14215         }
14216
14217         log "Test: ${cmd[*]}"
14218         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
14219
14220         if [ $JOBENV = "FAKE_JOBID" ]; then
14221                 FAKE_JOBID=$JOBVAL ${cmd[*]}
14222         else
14223                 ${cmd[*]}
14224         fi
14225
14226         # all files are created on OST0000
14227         for facet in $facets; do
14228                 local stats="*.$(convert_facet2label $facet).job_stats"
14229
14230                 # strip out libtool wrappers for in-tree executables
14231                 if [ $(do_facet $facet lctl get_param $stats |
14232                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
14233                         do_facet $facet lctl get_param $stats
14234                         error "No jobstats for $JOBVAL found on $facet::$stats"
14235                 fi
14236         done
14237 }
14238
14239 jobstats_set() {
14240         local new_jobenv=$1
14241
14242         set_persistent_param_and_check client "jobid_var" \
14243                 "$FSNAME.sys.jobid_var" $new_jobenv
14244 }
14245
14246 test_205() { # Job stats
14247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14248         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
14249                 skip "Need MDS version with at least 2.7.1"
14250         remote_mgs_nodsh && skip "remote MGS with nodsh"
14251         remote_mds_nodsh && skip "remote MDS with nodsh"
14252         remote_ost_nodsh && skip "remote OST with nodsh"
14253         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
14254                 skip "Server doesn't support jobstats"
14255         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
14256
14257         local old_jobenv=$($LCTL get_param -n jobid_var)
14258         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
14259
14260         if [[ $PERM_CMD == *"set_param -P"* ]]; then
14261                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
14262         else
14263                 stack_trap "do_facet mgs $PERM_CMD \
14264                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
14265         fi
14266         changelog_register
14267
14268         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
14269                                 mdt.*.job_cleanup_interval | head -n 1)
14270         local new_interval=5
14271         do_facet $SINGLEMDS \
14272                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
14273         stack_trap "do_facet $SINGLEMDS \
14274                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
14275         local start=$SECONDS
14276
14277         local cmd
14278         # mkdir
14279         cmd="mkdir $DIR/$tdir"
14280         verify_jobstats "$cmd" "$SINGLEMDS"
14281         # rmdir
14282         cmd="rmdir $DIR/$tdir"
14283         verify_jobstats "$cmd" "$SINGLEMDS"
14284         # mkdir on secondary MDT
14285         if [ $MDSCOUNT -gt 1 ]; then
14286                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
14287                 verify_jobstats "$cmd" "mds2"
14288         fi
14289         # mknod
14290         cmd="mknod $DIR/$tfile c 1 3"
14291         verify_jobstats "$cmd" "$SINGLEMDS"
14292         # unlink
14293         cmd="rm -f $DIR/$tfile"
14294         verify_jobstats "$cmd" "$SINGLEMDS"
14295         # create all files on OST0000 so verify_jobstats can find OST stats
14296         # open & close
14297         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
14298         verify_jobstats "$cmd" "$SINGLEMDS"
14299         # setattr
14300         cmd="touch $DIR/$tfile"
14301         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14302         # write
14303         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
14304         verify_jobstats "$cmd" "ost1"
14305         # read
14306         cancel_lru_locks osc
14307         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
14308         verify_jobstats "$cmd" "ost1"
14309         # truncate
14310         cmd="$TRUNCATE $DIR/$tfile 0"
14311         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14312         # rename
14313         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
14314         verify_jobstats "$cmd" "$SINGLEMDS"
14315         # jobstats expiry - sleep until old stats should be expired
14316         local left=$((new_interval + 5 - (SECONDS - start)))
14317         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
14318                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
14319                         "0" $left
14320         cmd="mkdir $DIR/$tdir.expire"
14321         verify_jobstats "$cmd" "$SINGLEMDS"
14322         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
14323             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
14324
14325         # Ensure that jobid are present in changelog (if supported by MDS)
14326         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
14327                 changelog_dump | tail -10
14328                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
14329                 [ $jobids -eq 9 ] ||
14330                         error "Wrong changelog jobid count $jobids != 9"
14331
14332                 # LU-5862
14333                 JOBENV="disable"
14334                 jobstats_set $JOBENV
14335                 touch $DIR/$tfile
14336                 changelog_dump | grep $tfile
14337                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
14338                 [ $jobids -eq 0 ] ||
14339                         error "Unexpected jobids when jobid_var=$JOBENV"
14340         fi
14341
14342         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
14343         JOBENV="JOBCOMPLEX"
14344         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
14345
14346         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
14347 }
14348 run_test 205 "Verify job stats"
14349
14350 # LU-1480, LU-1773 and LU-1657
14351 test_206() {
14352         mkdir -p $DIR/$tdir
14353         $LFS setstripe -c -1 $DIR/$tdir
14354 #define OBD_FAIL_LOV_INIT 0x1403
14355         $LCTL set_param fail_loc=0xa0001403
14356         $LCTL set_param fail_val=1
14357         touch $DIR/$tdir/$tfile || true
14358 }
14359 run_test 206 "fail lov_init_raid0() doesn't lbug"
14360
14361 test_207a() {
14362         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14363         local fsz=`stat -c %s $DIR/$tfile`
14364         cancel_lru_locks mdc
14365
14366         # do not return layout in getattr intent
14367 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
14368         $LCTL set_param fail_loc=0x170
14369         local sz=`stat -c %s $DIR/$tfile`
14370
14371         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
14372
14373         rm -rf $DIR/$tfile
14374 }
14375 run_test 207a "can refresh layout at glimpse"
14376
14377 test_207b() {
14378         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14379         local cksum=`md5sum $DIR/$tfile`
14380         local fsz=`stat -c %s $DIR/$tfile`
14381         cancel_lru_locks mdc
14382         cancel_lru_locks osc
14383
14384         # do not return layout in getattr intent
14385 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
14386         $LCTL set_param fail_loc=0x171
14387
14388         # it will refresh layout after the file is opened but before read issues
14389         echo checksum is "$cksum"
14390         echo "$cksum" |md5sum -c --quiet || error "file differs"
14391
14392         rm -rf $DIR/$tfile
14393 }
14394 run_test 207b "can refresh layout at open"
14395
14396 test_208() {
14397         # FIXME: in this test suite, only RD lease is used. This is okay
14398         # for now as only exclusive open is supported. After generic lease
14399         # is done, this test suite should be revised. - Jinshan
14400
14401         remote_mds_nodsh && skip "remote MDS with nodsh"
14402         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
14403                 skip "Need MDS version at least 2.4.52"
14404
14405         echo "==== test 1: verify get lease work"
14406         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
14407
14408         echo "==== test 2: verify lease can be broken by upcoming open"
14409         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14410         local PID=$!
14411         sleep 1
14412
14413         $MULTIOP $DIR/$tfile oO_RDONLY:c
14414         kill -USR1 $PID && wait $PID || error "break lease error"
14415
14416         echo "==== test 3: verify lease can't be granted if an open already exists"
14417         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
14418         local PID=$!
14419         sleep 1
14420
14421         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
14422         kill -USR1 $PID && wait $PID || error "open file error"
14423
14424         echo "==== test 4: lease can sustain over recovery"
14425         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
14426         PID=$!
14427         sleep 1
14428
14429         fail mds1
14430
14431         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
14432
14433         echo "==== test 5: lease broken can't be regained by replay"
14434         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14435         PID=$!
14436         sleep 1
14437
14438         # open file to break lease and then recovery
14439         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
14440         fail mds1
14441
14442         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
14443
14444         rm -f $DIR/$tfile
14445 }
14446 run_test 208 "Exclusive open"
14447
14448 test_209() {
14449         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
14450                 skip_env "must have disp_stripe"
14451
14452         touch $DIR/$tfile
14453         sync; sleep 5; sync;
14454
14455         echo 3 > /proc/sys/vm/drop_caches
14456         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14457
14458         # open/close 500 times
14459         for i in $(seq 500); do
14460                 cat $DIR/$tfile
14461         done
14462
14463         echo 3 > /proc/sys/vm/drop_caches
14464         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14465
14466         echo "before: $req_before, after: $req_after"
14467         [ $((req_after - req_before)) -ge 300 ] &&
14468                 error "open/close requests are not freed"
14469         return 0
14470 }
14471 run_test 209 "read-only open/close requests should be freed promptly"
14472
14473 test_212() {
14474         size=`date +%s`
14475         size=$((size % 8192 + 1))
14476         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
14477         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
14478         rm -f $DIR/f212 $DIR/f212.xyz
14479 }
14480 run_test 212 "Sendfile test ============================================"
14481
14482 test_213() {
14483         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
14484         cancel_lru_locks osc
14485         lctl set_param fail_loc=0x8000040f
14486         # generate a read lock
14487         cat $DIR/$tfile > /dev/null
14488         # write to the file, it will try to cancel the above read lock.
14489         cat /etc/hosts >> $DIR/$tfile
14490 }
14491 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
14492
14493 test_214() { # for bug 20133
14494         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
14495         for (( i=0; i < 340; i++ )) ; do
14496                 touch $DIR/$tdir/d214c/a$i
14497         done
14498
14499         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
14500         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
14501         ls $DIR/d214c || error "ls $DIR/d214c failed"
14502         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
14503         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
14504 }
14505 run_test 214 "hash-indexed directory test - bug 20133"
14506
14507 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
14508 create_lnet_proc_files() {
14509         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
14510 }
14511
14512 # counterpart of create_lnet_proc_files
14513 remove_lnet_proc_files() {
14514         rm -f $TMP/lnet_$1.sys
14515 }
14516
14517 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14518 # 3rd arg as regexp for body
14519 check_lnet_proc_stats() {
14520         local l=$(cat "$TMP/lnet_$1" |wc -l)
14521         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
14522
14523         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
14524 }
14525
14526 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14527 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
14528 # optional and can be regexp for 2nd line (lnet.routes case)
14529 check_lnet_proc_entry() {
14530         local blp=2          # blp stands for 'position of 1st line of body'
14531         [ -z "$5" ] || blp=3 # lnet.routes case
14532
14533         local l=$(cat "$TMP/lnet_$1" |wc -l)
14534         # subtracting one from $blp because the body can be empty
14535         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
14536
14537         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
14538                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
14539
14540         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
14541                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
14542
14543         # bail out if any unexpected line happened
14544         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
14545         [ "$?" != 0 ] || error "$2 misformatted"
14546 }
14547
14548 test_215() { # for bugs 18102, 21079, 21517
14549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14550
14551         local N='(0|[1-9][0-9]*)'       # non-negative numeric
14552         local P='[1-9][0-9]*'           # positive numeric
14553         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
14554         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
14555         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
14556         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
14557
14558         local L1 # regexp for 1st line
14559         local L2 # regexp for 2nd line (optional)
14560         local BR # regexp for the rest (body)
14561
14562         # lnet.stats should look as 11 space-separated non-negative numerics
14563         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
14564         create_lnet_proc_files "stats"
14565         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
14566         remove_lnet_proc_files "stats"
14567
14568         # lnet.routes should look like this:
14569         # Routing disabled/enabled
14570         # net hops priority state router
14571         # where net is a string like tcp0, hops > 0, priority >= 0,
14572         # state is up/down,
14573         # router is a string like 192.168.1.1@tcp2
14574         L1="^Routing (disabled|enabled)$"
14575         L2="^net +hops +priority +state +router$"
14576         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
14577         create_lnet_proc_files "routes"
14578         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
14579         remove_lnet_proc_files "routes"
14580
14581         # lnet.routers should look like this:
14582         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
14583         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
14584         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
14585         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
14586         L1="^ref +rtr_ref +alive_cnt +state +last_ping +ping_sent +deadline +down_ni +router$"
14587         BR="^$P +$P +$N +(up|down) +$N +(0|1) +$I +$I +$NID$"
14588         create_lnet_proc_files "routers"
14589         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
14590         remove_lnet_proc_files "routers"
14591
14592         # lnet.peers should look like this:
14593         # nid refs state last max rtr min tx min queue
14594         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
14595         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
14596         # numeric (0 or >0 or <0), queue >= 0.
14597         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
14598         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
14599         create_lnet_proc_files "peers"
14600         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
14601         remove_lnet_proc_files "peers"
14602
14603         # lnet.buffers  should look like this:
14604         # pages count credits min
14605         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
14606         L1="^pages +count +credits +min$"
14607         BR="^ +$N +$N +$I +$I$"
14608         create_lnet_proc_files "buffers"
14609         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
14610         remove_lnet_proc_files "buffers"
14611
14612         # lnet.nis should look like this:
14613         # nid status alive refs peer rtr max tx min
14614         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
14615         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
14616         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
14617         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
14618         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
14619         create_lnet_proc_files "nis"
14620         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
14621         remove_lnet_proc_files "nis"
14622
14623         # can we successfully write to lnet.stats?
14624         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
14625 }
14626 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
14627
14628 test_216() { # bug 20317
14629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14630         remote_ost_nodsh && skip "remote OST with nodsh"
14631
14632         local node
14633         local facets=$(get_facets OST)
14634         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14635
14636         save_lustre_params client "osc.*.contention_seconds" > $p
14637         save_lustre_params $facets \
14638                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
14639         save_lustre_params $facets \
14640                 "ldlm.namespaces.filter-*.contended_locks" >> $p
14641         save_lustre_params $facets \
14642                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
14643         clear_stats osc.*.osc_stats
14644
14645         # agressive lockless i/o settings
14646         do_nodes $(comma_list $(osts_nodes)) \
14647                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
14648                         ldlm.namespaces.filter-*.contended_locks=0 \
14649                         ldlm.namespaces.filter-*.contention_seconds=60"
14650         lctl set_param -n osc.*.contention_seconds=60
14651
14652         $DIRECTIO write $DIR/$tfile 0 10 4096
14653         $CHECKSTAT -s 40960 $DIR/$tfile
14654
14655         # disable lockless i/o
14656         do_nodes $(comma_list $(osts_nodes)) \
14657                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
14658                         ldlm.namespaces.filter-*.contended_locks=32 \
14659                         ldlm.namespaces.filter-*.contention_seconds=0"
14660         lctl set_param -n osc.*.contention_seconds=0
14661         clear_stats osc.*.osc_stats
14662
14663         dd if=/dev/zero of=$DIR/$tfile count=0
14664         $CHECKSTAT -s 0 $DIR/$tfile
14665
14666         restore_lustre_params <$p
14667         rm -f $p
14668         rm $DIR/$tfile
14669 }
14670 run_test 216 "check lockless direct write updates file size and kms correctly"
14671
14672 test_217() { # bug 22430
14673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14674
14675         local node
14676         local nid
14677
14678         for node in $(nodes_list); do
14679                 nid=$(host_nids_address $node $NETTYPE)
14680                 if [[ $nid = *-* ]] ; then
14681                         echo "lctl ping $(h2nettype $nid)"
14682                         lctl ping $(h2nettype $nid)
14683                 else
14684                         echo "skipping $node (no hyphen detected)"
14685                 fi
14686         done
14687 }
14688 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
14689
14690 test_218() {
14691        # do directio so as not to populate the page cache
14692        log "creating a 10 Mb file"
14693        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
14694        log "starting reads"
14695        dd if=$DIR/$tfile of=/dev/null bs=4096 &
14696        log "truncating the file"
14697        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
14698        log "killing dd"
14699        kill %+ || true # reads might have finished
14700        echo "wait until dd is finished"
14701        wait
14702        log "removing the temporary file"
14703        rm -rf $DIR/$tfile || error "tmp file removal failed"
14704 }
14705 run_test 218 "parallel read and truncate should not deadlock"
14706
14707 test_219() {
14708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14709
14710         # write one partial page
14711         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
14712         # set no grant so vvp_io_commit_write will do sync write
14713         $LCTL set_param fail_loc=0x411
14714         # write a full page at the end of file
14715         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
14716
14717         $LCTL set_param fail_loc=0
14718         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
14719         $LCTL set_param fail_loc=0x411
14720         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
14721
14722         # LU-4201
14723         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
14724         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
14725 }
14726 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
14727
14728 test_220() { #LU-325
14729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14730         remote_ost_nodsh && skip "remote OST with nodsh"
14731         remote_mds_nodsh && skip "remote MDS with nodsh"
14732         remote_mgs_nodsh && skip "remote MGS with nodsh"
14733
14734         local OSTIDX=0
14735
14736         # create on MDT0000 so the last_id and next_id are correct
14737         mkdir $DIR/$tdir
14738         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
14739         OST=${OST%_UUID}
14740
14741         # on the mdt's osc
14742         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
14743         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
14744                         osc.$mdtosc_proc1.prealloc_last_id)
14745         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
14746                         osc.$mdtosc_proc1.prealloc_next_id)
14747
14748         $LFS df -i
14749
14750         if ! combined_mgs_mds ; then
14751                 mount_mgs_client
14752         fi
14753
14754         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
14755         #define OBD_FAIL_OST_ENOINO              0x229
14756         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
14757         create_pool $FSNAME.$TESTNAME || return 1
14758         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
14759
14760         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
14761
14762         MDSOBJS=$((last_id - next_id))
14763         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
14764
14765         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
14766         echo "OST still has $count kbytes free"
14767
14768         echo "create $MDSOBJS files @next_id..."
14769         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
14770
14771         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
14772                         osc.$mdtosc_proc1.prealloc_last_id)
14773         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
14774                         osc.$mdtosc_proc1.prealloc_next_id)
14775
14776         echo "after creation, last_id=$last_id2, next_id=$next_id2"
14777         $LFS df -i
14778
14779         echo "cleanup..."
14780
14781         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
14782         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
14783
14784         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
14785                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
14786         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
14787                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
14788         echo "unlink $MDSOBJS files @$next_id..."
14789         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
14790
14791         if ! combined_mgs_mds ; then
14792                 umount_mgs_client
14793         fi
14794 }
14795 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
14796
14797 test_221() {
14798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14799
14800         dd if=`which date` of=$MOUNT/date oflag=sync
14801         chmod +x $MOUNT/date
14802
14803         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
14804         $LCTL set_param fail_loc=0x80001401
14805
14806         $MOUNT/date > /dev/null
14807         rm -f $MOUNT/date
14808 }
14809 run_test 221 "make sure fault and truncate race to not cause OOM"
14810
14811 test_222a () {
14812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14813
14814         rm -rf $DIR/$tdir
14815         test_mkdir $DIR/$tdir
14816         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14817         createmany -o $DIR/$tdir/$tfile 10
14818         cancel_lru_locks mdc
14819         cancel_lru_locks osc
14820         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
14821         $LCTL set_param fail_loc=0x31a
14822         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
14823         $LCTL set_param fail_loc=0
14824         rm -r $DIR/$tdir
14825 }
14826 run_test 222a "AGL for ls should not trigger CLIO lock failure"
14827
14828 test_222b () {
14829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14830
14831         rm -rf $DIR/$tdir
14832         test_mkdir $DIR/$tdir
14833         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14834         createmany -o $DIR/$tdir/$tfile 10
14835         cancel_lru_locks mdc
14836         cancel_lru_locks osc
14837         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
14838         $LCTL set_param fail_loc=0x31a
14839         rm -r $DIR/$tdir || error "AGL for rmdir failed"
14840         $LCTL set_param fail_loc=0
14841 }
14842 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
14843
14844 test_223 () {
14845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14846
14847         rm -rf $DIR/$tdir
14848         test_mkdir $DIR/$tdir
14849         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14850         createmany -o $DIR/$tdir/$tfile 10
14851         cancel_lru_locks mdc
14852         cancel_lru_locks osc
14853         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
14854         $LCTL set_param fail_loc=0x31b
14855         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
14856         $LCTL set_param fail_loc=0
14857         rm -r $DIR/$tdir
14858 }
14859 run_test 223 "osc reenqueue if without AGL lock granted ======================="
14860
14861 test_224a() { # LU-1039, MRP-303
14862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14863
14864         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
14865         $LCTL set_param fail_loc=0x508
14866         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
14867         $LCTL set_param fail_loc=0
14868         df $DIR
14869 }
14870 run_test 224a "Don't panic on bulk IO failure"
14871
14872 test_224b() { # LU-1039, MRP-303
14873         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14874
14875         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
14876         cancel_lru_locks osc
14877         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
14878         $LCTL set_param fail_loc=0x515
14879         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
14880         $LCTL set_param fail_loc=0
14881         df $DIR
14882 }
14883 run_test 224b "Don't panic on bulk IO failure"
14884
14885 test_224c() { # LU-6441
14886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14887         remote_mds_nodsh && skip "remote MDS with nodsh"
14888
14889         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14890         save_writethrough $p
14891         set_cache writethrough on
14892
14893         local pages_per_rpc=$($LCTL get_param \
14894                                 osc.*.max_pages_per_rpc)
14895         local at_max=$($LCTL get_param -n at_max)
14896         local timeout=$($LCTL get_param -n timeout)
14897         local test_at="at_max"
14898         local param_at="$FSNAME.sys.at_max"
14899         local test_timeout="timeout"
14900         local param_timeout="$FSNAME.sys.timeout"
14901
14902         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
14903
14904         set_persistent_param_and_check client "$test_at" "$param_at" 0
14905         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
14906
14907         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
14908         do_facet ost1 "$LCTL set_param fail_loc=0x520"
14909         $LFS setstripe -c 1 -i 0 $DIR/$tfile
14910         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
14911         sync
14912         do_facet ost1 "$LCTL set_param fail_loc=0"
14913
14914         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
14915         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
14916                 $timeout
14917
14918         $LCTL set_param -n $pages_per_rpc
14919         restore_lustre_params < $p
14920         rm -f $p
14921 }
14922 run_test 224c "Don't hang if one of md lost during large bulk RPC"
14923
14924 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
14925 test_225a () {
14926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14927         if [ -z ${MDSSURVEY} ]; then
14928                 skip_env "mds-survey not found"
14929         fi
14930         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
14931                 skip "Need MDS version at least 2.2.51"
14932
14933         local mds=$(facet_host $SINGLEMDS)
14934         local target=$(do_nodes $mds 'lctl dl' |
14935                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
14936
14937         local cmd1="file_count=1000 thrhi=4"
14938         local cmd2="dir_count=2 layer=mdd stripe_count=0"
14939         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
14940         local cmd="$cmd1 $cmd2 $cmd3"
14941
14942         rm -f ${TMP}/mds_survey*
14943         echo + $cmd
14944         eval $cmd || error "mds-survey with zero-stripe failed"
14945         cat ${TMP}/mds_survey*
14946         rm -f ${TMP}/mds_survey*
14947 }
14948 run_test 225a "Metadata survey sanity with zero-stripe"
14949
14950 test_225b () {
14951         if [ -z ${MDSSURVEY} ]; then
14952                 skip_env "mds-survey not found"
14953         fi
14954         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
14955                 skip "Need MDS version at least 2.2.51"
14956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14957         remote_mds_nodsh && skip "remote MDS with nodsh"
14958         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
14959                 skip_env "Need to mount OST to test"
14960         fi
14961
14962         local mds=$(facet_host $SINGLEMDS)
14963         local target=$(do_nodes $mds 'lctl dl' |
14964                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
14965
14966         local cmd1="file_count=1000 thrhi=4"
14967         local cmd2="dir_count=2 layer=mdd stripe_count=1"
14968         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
14969         local cmd="$cmd1 $cmd2 $cmd3"
14970
14971         rm -f ${TMP}/mds_survey*
14972         echo + $cmd
14973         eval $cmd || error "mds-survey with stripe_count failed"
14974         cat ${TMP}/mds_survey*
14975         rm -f ${TMP}/mds_survey*
14976 }
14977 run_test 225b "Metadata survey sanity with stripe_count = 1"
14978
14979 mcreate_path2fid () {
14980         local mode=$1
14981         local major=$2
14982         local minor=$3
14983         local name=$4
14984         local desc=$5
14985         local path=$DIR/$tdir/$name
14986         local fid
14987         local rc
14988         local fid_path
14989
14990         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
14991                 error "cannot create $desc"
14992
14993         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
14994         rc=$?
14995         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
14996
14997         fid_path=$($LFS fid2path $MOUNT $fid)
14998         rc=$?
14999         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
15000
15001         [ "$path" == "$fid_path" ] ||
15002                 error "fid2path returned $fid_path, expected $path"
15003
15004         echo "pass with $path and $fid"
15005 }
15006
15007 test_226a () {
15008         rm -rf $DIR/$tdir
15009         mkdir -p $DIR/$tdir
15010
15011         mcreate_path2fid 0010666 0 0 fifo "FIFO"
15012         mcreate_path2fid 0020666 1 3 null "character special file (null)"
15013         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
15014         mcreate_path2fid 0040666 0 0 dir "directory"
15015         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
15016         mcreate_path2fid 0100666 0 0 file "regular file"
15017         mcreate_path2fid 0120666 0 0 link "symbolic link"
15018         mcreate_path2fid 0140666 0 0 sock "socket"
15019 }
15020 run_test 226a "call path2fid and fid2path on files of all type"
15021
15022 test_226b () {
15023         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15024
15025         local MDTIDX=1
15026
15027         rm -rf $DIR/$tdir
15028         mkdir -p $DIR/$tdir
15029         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
15030                 error "create remote directory failed"
15031         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
15032         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
15033                                 "character special file (null)"
15034         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
15035                                 "character special file (no device)"
15036         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
15037         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
15038                                 "block special file (loop)"
15039         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
15040         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
15041         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
15042 }
15043 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
15044
15045 # LU-1299 Executing or running ldd on a truncated executable does not
15046 # cause an out-of-memory condition.
15047 test_227() {
15048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15049         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
15050
15051         dd if=$(which date) of=$MOUNT/date bs=1k count=1
15052         chmod +x $MOUNT/date
15053
15054         $MOUNT/date > /dev/null
15055         ldd $MOUNT/date > /dev/null
15056         rm -f $MOUNT/date
15057 }
15058 run_test 227 "running truncated executable does not cause OOM"
15059
15060 # LU-1512 try to reuse idle OI blocks
15061 test_228a() {
15062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15063         remote_mds_nodsh && skip "remote MDS with nodsh"
15064         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15065
15066         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15067         local myDIR=$DIR/$tdir
15068
15069         mkdir -p $myDIR
15070         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15071         $LCTL set_param fail_loc=0x80001002
15072         createmany -o $myDIR/t- 10000
15073         $LCTL set_param fail_loc=0
15074         # The guard is current the largest FID holder
15075         touch $myDIR/guard
15076         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15077                     tr -d '[')
15078         local IDX=$(($SEQ % 64))
15079
15080         do_facet $SINGLEMDS sync
15081         # Make sure journal flushed.
15082         sleep 6
15083         local blk1=$(do_facet $SINGLEMDS \
15084                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15085                      grep Blockcount | awk '{print $4}')
15086
15087         # Remove old files, some OI blocks will become idle.
15088         unlinkmany $myDIR/t- 10000
15089         # Create new files, idle OI blocks should be reused.
15090         createmany -o $myDIR/t- 2000
15091         do_facet $SINGLEMDS sync
15092         # Make sure journal flushed.
15093         sleep 6
15094         local blk2=$(do_facet $SINGLEMDS \
15095                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15096                      grep Blockcount | awk '{print $4}')
15097
15098         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15099 }
15100 run_test 228a "try to reuse idle OI blocks"
15101
15102 test_228b() {
15103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15104         remote_mds_nodsh && skip "remote MDS with nodsh"
15105         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15106
15107         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15108         local myDIR=$DIR/$tdir
15109
15110         mkdir -p $myDIR
15111         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15112         $LCTL set_param fail_loc=0x80001002
15113         createmany -o $myDIR/t- 10000
15114         $LCTL set_param fail_loc=0
15115         # The guard is current the largest FID holder
15116         touch $myDIR/guard
15117         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15118                     tr -d '[')
15119         local IDX=$(($SEQ % 64))
15120
15121         do_facet $SINGLEMDS sync
15122         # Make sure journal flushed.
15123         sleep 6
15124         local blk1=$(do_facet $SINGLEMDS \
15125                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15126                      grep Blockcount | awk '{print $4}')
15127
15128         # Remove old files, some OI blocks will become idle.
15129         unlinkmany $myDIR/t- 10000
15130
15131         # stop the MDT
15132         stop $SINGLEMDS || error "Fail to stop MDT."
15133         # remount the MDT
15134         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
15135
15136         df $MOUNT || error "Fail to df."
15137         # Create new files, idle OI blocks should be reused.
15138         createmany -o $myDIR/t- 2000
15139         do_facet $SINGLEMDS sync
15140         # Make sure journal flushed.
15141         sleep 6
15142         local blk2=$(do_facet $SINGLEMDS \
15143                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15144                      grep Blockcount | awk '{print $4}')
15145
15146         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15147 }
15148 run_test 228b "idle OI blocks can be reused after MDT restart"
15149
15150 #LU-1881
15151 test_228c() {
15152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15153         remote_mds_nodsh && skip "remote MDS with nodsh"
15154         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15155
15156         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15157         local myDIR=$DIR/$tdir
15158
15159         mkdir -p $myDIR
15160         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15161         $LCTL set_param fail_loc=0x80001002
15162         # 20000 files can guarantee there are index nodes in the OI file
15163         createmany -o $myDIR/t- 20000
15164         $LCTL set_param fail_loc=0
15165         # The guard is current the largest FID holder
15166         touch $myDIR/guard
15167         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15168                     tr -d '[')
15169         local IDX=$(($SEQ % 64))
15170
15171         do_facet $SINGLEMDS sync
15172         # Make sure journal flushed.
15173         sleep 6
15174         local blk1=$(do_facet $SINGLEMDS \
15175                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15176                      grep Blockcount | awk '{print $4}')
15177
15178         # Remove old files, some OI blocks will become idle.
15179         unlinkmany $myDIR/t- 20000
15180         rm -f $myDIR/guard
15181         # The OI file should become empty now
15182
15183         # Create new files, idle OI blocks should be reused.
15184         createmany -o $myDIR/t- 2000
15185         do_facet $SINGLEMDS sync
15186         # Make sure journal flushed.
15187         sleep 6
15188         local blk2=$(do_facet $SINGLEMDS \
15189                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15190                      grep Blockcount | awk '{print $4}')
15191
15192         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15193 }
15194 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
15195
15196 test_229() { # LU-2482, LU-3448
15197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15198         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
15199         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
15200                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
15201
15202         rm -f $DIR/$tfile
15203
15204         # Create a file with a released layout and stripe count 2.
15205         $MULTIOP $DIR/$tfile H2c ||
15206                 error "failed to create file with released layout"
15207
15208         $LFS getstripe -v $DIR/$tfile
15209
15210         local pattern=$($LFS getstripe -L $DIR/$tfile)
15211         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
15212
15213         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
15214                 error "getstripe"
15215         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
15216         stat $DIR/$tfile || error "failed to stat released file"
15217
15218         chown $RUNAS_ID $DIR/$tfile ||
15219                 error "chown $RUNAS_ID $DIR/$tfile failed"
15220
15221         chgrp $RUNAS_ID $DIR/$tfile ||
15222                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
15223
15224         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
15225         rm $DIR/$tfile || error "failed to remove released file"
15226 }
15227 run_test 229 "getstripe/stat/rm/attr changes work on released files"
15228
15229 test_230a() {
15230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15231         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15232         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15233                 skip "Need MDS version at least 2.11.52"
15234
15235         local MDTIDX=1
15236
15237         test_mkdir $DIR/$tdir
15238         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
15239         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
15240         [ $mdt_idx -ne 0 ] &&
15241                 error "create local directory on wrong MDT $mdt_idx"
15242
15243         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
15244                         error "create remote directory failed"
15245         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
15246         [ $mdt_idx -ne $MDTIDX ] &&
15247                 error "create remote directory on wrong MDT $mdt_idx"
15248
15249         createmany -o $DIR/$tdir/test_230/t- 10 ||
15250                 error "create files on remote directory failed"
15251         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
15252         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
15253         rm -r $DIR/$tdir || error "unlink remote directory failed"
15254 }
15255 run_test 230a "Create remote directory and files under the remote directory"
15256
15257 test_230b() {
15258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15259         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15260         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15261                 skip "Need MDS version at least 2.11.52"
15262
15263         local MDTIDX=1
15264         local mdt_index
15265         local i
15266         local file
15267         local pid
15268         local stripe_count
15269         local migrate_dir=$DIR/$tdir/migrate_dir
15270         local other_dir=$DIR/$tdir/other_dir
15271
15272         test_mkdir $DIR/$tdir
15273         test_mkdir -i0 -c1 $migrate_dir
15274         test_mkdir -i0 -c1 $other_dir
15275         for ((i=0; i<10; i++)); do
15276                 mkdir -p $migrate_dir/dir_${i}
15277                 createmany -o $migrate_dir/dir_${i}/f 10 ||
15278                         error "create files under remote dir failed $i"
15279         done
15280
15281         cp /etc/passwd $migrate_dir/$tfile
15282         cp /etc/passwd $other_dir/$tfile
15283         chattr +SAD $migrate_dir
15284         chattr +SAD $migrate_dir/$tfile
15285
15286         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15287         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15288         local old_dir_mode=$(stat -c%f $migrate_dir)
15289         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
15290
15291         mkdir -p $migrate_dir/dir_default_stripe2
15292         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
15293         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
15294
15295         mkdir -p $other_dir
15296         ln $migrate_dir/$tfile $other_dir/luna
15297         ln $migrate_dir/$tfile $migrate_dir/sofia
15298         ln $other_dir/$tfile $migrate_dir/david
15299         ln -s $migrate_dir/$tfile $other_dir/zachary
15300         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
15301         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
15302
15303         $LFS migrate -m $MDTIDX $migrate_dir ||
15304                 error "fails on migrating remote dir to MDT1"
15305
15306         echo "migratate to MDT1, then checking.."
15307         for ((i = 0; i < 10; i++)); do
15308                 for file in $(find $migrate_dir/dir_${i}); do
15309                         mdt_index=$($LFS getstripe -m $file)
15310                         [ $mdt_index == $MDTIDX ] ||
15311                                 error "$file is not on MDT${MDTIDX}"
15312                 done
15313         done
15314
15315         # the multiple link file should still in MDT0
15316         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
15317         [ $mdt_index == 0 ] ||
15318                 error "$file is not on MDT${MDTIDX}"
15319
15320         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15321         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15322                 error " expect $old_dir_flag get $new_dir_flag"
15323
15324         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15325         [ "$old_file_flag" = "$new_file_flag" ] ||
15326                 error " expect $old_file_flag get $new_file_flag"
15327
15328         local new_dir_mode=$(stat -c%f $migrate_dir)
15329         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15330                 error "expect mode $old_dir_mode get $new_dir_mode"
15331
15332         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15333         [ "$old_file_mode" = "$new_file_mode" ] ||
15334                 error "expect mode $old_file_mode get $new_file_mode"
15335
15336         diff /etc/passwd $migrate_dir/$tfile ||
15337                 error "$tfile different after migration"
15338
15339         diff /etc/passwd $other_dir/luna ||
15340                 error "luna different after migration"
15341
15342         diff /etc/passwd $migrate_dir/sofia ||
15343                 error "sofia different after migration"
15344
15345         diff /etc/passwd $migrate_dir/david ||
15346                 error "david different after migration"
15347
15348         diff /etc/passwd $other_dir/zachary ||
15349                 error "zachary different after migration"
15350
15351         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15352                 error "${tfile}_ln different after migration"
15353
15354         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15355                 error "${tfile}_ln_other different after migration"
15356
15357         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
15358         [ $stripe_count = 2 ] ||
15359                 error "dir strpe_count $d != 2 after migration."
15360
15361         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
15362         [ $stripe_count = 2 ] ||
15363                 error "file strpe_count $d != 2 after migration."
15364
15365         #migrate back to MDT0
15366         MDTIDX=0
15367
15368         $LFS migrate -m $MDTIDX $migrate_dir ||
15369                 error "fails on migrating remote dir to MDT0"
15370
15371         echo "migrate back to MDT0, checking.."
15372         for file in $(find $migrate_dir); do
15373                 mdt_index=$($LFS getstripe -m $file)
15374                 [ $mdt_index == $MDTIDX ] ||
15375                         error "$file is not on MDT${MDTIDX}"
15376         done
15377
15378         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15379         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15380                 error " expect $old_dir_flag get $new_dir_flag"
15381
15382         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15383         [ "$old_file_flag" = "$new_file_flag" ] ||
15384                 error " expect $old_file_flag get $new_file_flag"
15385
15386         local new_dir_mode=$(stat -c%f $migrate_dir)
15387         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15388                 error "expect mode $old_dir_mode get $new_dir_mode"
15389
15390         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15391         [ "$old_file_mode" = "$new_file_mode" ] ||
15392                 error "expect mode $old_file_mode get $new_file_mode"
15393
15394         diff /etc/passwd ${migrate_dir}/$tfile ||
15395                 error "$tfile different after migration"
15396
15397         diff /etc/passwd ${other_dir}/luna ||
15398                 error "luna different after migration"
15399
15400         diff /etc/passwd ${migrate_dir}/sofia ||
15401                 error "sofia different after migration"
15402
15403         diff /etc/passwd ${other_dir}/zachary ||
15404                 error "zachary different after migration"
15405
15406         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15407                 error "${tfile}_ln different after migration"
15408
15409         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15410                 error "${tfile}_ln_other different after migration"
15411
15412         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
15413         [ $stripe_count = 2 ] ||
15414                 error "dir strpe_count $d != 2 after migration."
15415
15416         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
15417         [ $stripe_count = 2 ] ||
15418                 error "file strpe_count $d != 2 after migration."
15419
15420         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15421 }
15422 run_test 230b "migrate directory"
15423
15424 test_230c() {
15425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15426         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15427         remote_mds_nodsh && skip "remote MDS with nodsh"
15428         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15429                 skip "Need MDS version at least 2.11.52"
15430
15431         local MDTIDX=1
15432         local total=3
15433         local mdt_index
15434         local file
15435         local migrate_dir=$DIR/$tdir/migrate_dir
15436
15437         #If migrating directory fails in the middle, all entries of
15438         #the directory is still accessiable.
15439         test_mkdir $DIR/$tdir
15440         test_mkdir -i0 -c1 $migrate_dir
15441         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
15442         stat $migrate_dir
15443         createmany -o $migrate_dir/f $total ||
15444                 error "create files under ${migrate_dir} failed"
15445
15446         # fail after migrating top dir, and this will fail only once, so the
15447         # first sub file migration will fail (currently f3), others succeed.
15448         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
15449         do_facet mds1 lctl set_param fail_loc=0x1801
15450         local t=$(ls $migrate_dir | wc -l)
15451         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
15452                 error "migrate should fail"
15453         local u=$(ls $migrate_dir | wc -l)
15454         [ "$u" == "$t" ] || error "$u != $t during migration"
15455
15456         # add new dir/file should succeed
15457         mkdir $migrate_dir/dir ||
15458                 error "mkdir failed under migrating directory"
15459         touch $migrate_dir/file ||
15460                 error "create file failed under migrating directory"
15461
15462         # add file with existing name should fail
15463         for file in $migrate_dir/f*; do
15464                 stat $file > /dev/null || error "stat $file failed"
15465                 $OPENFILE -f O_CREAT:O_EXCL $file &&
15466                         error "open(O_CREAT|O_EXCL) $file should fail"
15467                 $MULTIOP $file m && error "create $file should fail"
15468                 touch $DIR/$tdir/remote_dir/$tfile ||
15469                         error "touch $tfile failed"
15470                 ln $DIR/$tdir/remote_dir/$tfile $file &&
15471                         error "link $file should fail"
15472                 mdt_index=$($LFS getstripe -m $file)
15473                 if [ $mdt_index == 0 ]; then
15474                         # file failed to migrate is not allowed to rename to
15475                         mv $DIR/$tdir/remote_dir/$tfile $file &&
15476                                 error "rename to $file should fail"
15477                 else
15478                         mv $DIR/$tdir/remote_dir/$tfile $file ||
15479                                 error "rename to $file failed"
15480                 fi
15481                 echo hello >> $file || error "write $file failed"
15482         done
15483
15484         # resume migration with different options should fail
15485         $LFS migrate -m 0 $migrate_dir &&
15486                 error "migrate -m 0 $migrate_dir should fail"
15487
15488         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
15489                 error "migrate -c 2 $migrate_dir should fail"
15490
15491         # resume migration should succeed
15492         $LFS migrate -m $MDTIDX $migrate_dir ||
15493                 error "migrate $migrate_dir failed"
15494
15495         echo "Finish migration, then checking.."
15496         for file in $(find $migrate_dir); do
15497                 mdt_index=$($LFS getstripe -m $file)
15498                 [ $mdt_index == $MDTIDX ] ||
15499                         error "$file is not on MDT${MDTIDX}"
15500         done
15501
15502         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15503 }
15504 run_test 230c "check directory accessiblity if migration failed"
15505
15506 test_230d() {
15507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15508         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15509         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15510                 skip "Need MDS version at least 2.11.52"
15511         # LU-11235
15512         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
15513
15514         local migrate_dir=$DIR/$tdir/migrate_dir
15515         local old_index
15516         local new_index
15517         local old_count
15518         local new_count
15519         local new_hash
15520         local mdt_index
15521         local i
15522         local j
15523
15524         old_index=$((RANDOM % MDSCOUNT))
15525         old_count=$((MDSCOUNT - old_index))
15526         new_index=$((RANDOM % MDSCOUNT))
15527         new_count=$((MDSCOUNT - new_index))
15528         new_hash="all_char"
15529
15530         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
15531         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
15532
15533         test_mkdir $DIR/$tdir
15534         test_mkdir -i $old_index -c $old_count $migrate_dir
15535
15536         for ((i=0; i<100; i++)); do
15537                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
15538                 createmany -o $migrate_dir/dir_${i}/f 100 ||
15539                         error "create files under remote dir failed $i"
15540         done
15541
15542         echo -n "Migrate from MDT$old_index "
15543         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
15544         echo -n "to MDT$new_index"
15545         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
15546         echo
15547
15548         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
15549         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
15550                 error "migrate remote dir error"
15551
15552         echo "Finish migration, then checking.."
15553         for file in $(find $migrate_dir); do
15554                 mdt_index=$($LFS getstripe -m $file)
15555                 if [ $mdt_index -lt $new_index ] ||
15556                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
15557                         error "$file is on MDT$mdt_index"
15558                 fi
15559         done
15560
15561         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15562 }
15563 run_test 230d "check migrate big directory"
15564
15565 test_230e() {
15566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15567         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15568         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15569                 skip "Need MDS version at least 2.11.52"
15570
15571         local i
15572         local j
15573         local a_fid
15574         local b_fid
15575
15576         mkdir -p $DIR/$tdir
15577         mkdir $DIR/$tdir/migrate_dir
15578         mkdir $DIR/$tdir/other_dir
15579         touch $DIR/$tdir/migrate_dir/a
15580         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
15581         ls $DIR/$tdir/other_dir
15582
15583         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15584                 error "migrate dir fails"
15585
15586         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
15587         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
15588
15589         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15590         [ $mdt_index == 0 ] || error "a is not on MDT0"
15591
15592         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
15593                 error "migrate dir fails"
15594
15595         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
15596         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
15597
15598         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15599         [ $mdt_index == 1 ] || error "a is not on MDT1"
15600
15601         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
15602         [ $mdt_index == 1 ] || error "b is not on MDT1"
15603
15604         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
15605         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
15606
15607         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
15608
15609         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15610 }
15611 run_test 230e "migrate mulitple local link files"
15612
15613 test_230f() {
15614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15615         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15616         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15617                 skip "Need MDS version at least 2.11.52"
15618
15619         local a_fid
15620         local ln_fid
15621
15622         mkdir -p $DIR/$tdir
15623         mkdir $DIR/$tdir/migrate_dir
15624         $LFS mkdir -i1 $DIR/$tdir/other_dir
15625         touch $DIR/$tdir/migrate_dir/a
15626         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
15627         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
15628         ls $DIR/$tdir/other_dir
15629
15630         # a should be migrated to MDT1, since no other links on MDT0
15631         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15632                 error "#1 migrate dir fails"
15633         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
15634         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
15635         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15636         [ $mdt_index == 1 ] || error "a is not on MDT1"
15637
15638         # a should stay on MDT1, because it is a mulitple link file
15639         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
15640                 error "#2 migrate dir fails"
15641         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15642         [ $mdt_index == 1 ] || error "a is not on MDT1"
15643
15644         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15645                 error "#3 migrate dir fails"
15646
15647         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
15648         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
15649         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
15650
15651         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
15652         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
15653
15654         # a should be migrated to MDT0, since no other links on MDT1
15655         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
15656                 error "#4 migrate dir fails"
15657         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15658         [ $mdt_index == 0 ] || error "a is not on MDT0"
15659
15660         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15661 }
15662 run_test 230f "migrate mulitple remote link files"
15663
15664 test_230g() {
15665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15666         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15667         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15668                 skip "Need MDS version at least 2.11.52"
15669
15670         mkdir -p $DIR/$tdir/migrate_dir
15671
15672         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
15673                 error "migrating dir to non-exist MDT succeeds"
15674         true
15675 }
15676 run_test 230g "migrate dir to non-exist MDT"
15677
15678 test_230h() {
15679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15680         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15681         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15682                 skip "Need MDS version at least 2.11.52"
15683
15684         local mdt_index
15685
15686         mkdir -p $DIR/$tdir/migrate_dir
15687
15688         $LFS migrate -m1 $DIR &&
15689                 error "migrating mountpoint1 should fail"
15690
15691         $LFS migrate -m1 $DIR/$tdir/.. &&
15692                 error "migrating mountpoint2 should fail"
15693
15694         # same as mv
15695         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
15696                 error "migrating $tdir/migrate_dir/.. should fail"
15697
15698         true
15699 }
15700 run_test 230h "migrate .. and root"
15701
15702 test_230i() {
15703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15704         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15705         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15706                 skip "Need MDS version at least 2.11.52"
15707
15708         mkdir -p $DIR/$tdir/migrate_dir
15709
15710         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
15711                 error "migration fails with a tailing slash"
15712
15713         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
15714                 error "migration fails with two tailing slashes"
15715 }
15716 run_test 230i "lfs migrate -m tolerates trailing slashes"
15717
15718 test_230j() {
15719         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
15720         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15721                 skip "Need MDS version at least 2.11.52"
15722
15723         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
15724         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
15725                 error "create $tfile failed"
15726         cat /etc/passwd > $DIR/$tdir/$tfile
15727
15728         $LFS migrate -m 1 $DIR/$tdir
15729
15730         cmp /etc/passwd $DIR/$tdir/$tfile ||
15731                 error "DoM file mismatch after migration"
15732 }
15733 run_test 230j "DoM file data not changed after dir migration"
15734
15735 test_230k() {
15736         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
15737         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
15738                 skip "Need MDS version at least 2.11.56"
15739
15740         local total=20
15741         local files_on_starting_mdt=0
15742
15743         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
15744         $LFS getdirstripe $DIR/$tdir
15745         for i in $(seq $total); do
15746                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
15747                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
15748                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15749         done
15750
15751         echo "$files_on_starting_mdt files on MDT0"
15752
15753         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
15754         $LFS getdirstripe $DIR/$tdir
15755
15756         files_on_starting_mdt=0
15757         for i in $(seq $total); do
15758                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
15759                         error "file $tfile.$i mismatch after migration"
15760                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
15761                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15762         done
15763
15764         echo "$files_on_starting_mdt files on MDT1 after migration"
15765         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
15766
15767         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
15768         $LFS getdirstripe $DIR/$tdir
15769
15770         files_on_starting_mdt=0
15771         for i in $(seq $total); do
15772                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
15773                         error "file $tfile.$i mismatch after 2nd migration"
15774                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
15775                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15776         done
15777
15778         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
15779         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
15780
15781         true
15782 }
15783 run_test 230k "file data not changed after dir migration"
15784
15785 test_230l() {
15786         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
15787         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
15788                 skip "Need MDS version at least 2.11.56"
15789
15790         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
15791         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
15792                 error "create files under remote dir failed $i"
15793         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
15794 }
15795 run_test 230l "readdir between MDTs won't crash"
15796
15797 test_231a()
15798 {
15799         # For simplicity this test assumes that max_pages_per_rpc
15800         # is the same across all OSCs
15801         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
15802         local bulk_size=$((max_pages * PAGE_SIZE))
15803         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
15804                                        head -n 1)
15805
15806         mkdir -p $DIR/$tdir
15807         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
15808                 error "failed to set stripe with -S ${brw_size}M option"
15809
15810         # clear the OSC stats
15811         $LCTL set_param osc.*.stats=0 &>/dev/null
15812         stop_writeback
15813
15814         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
15815         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
15816                 oflag=direct &>/dev/null || error "dd failed"
15817
15818         sync; sleep 1; sync # just to be safe
15819         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
15820         if [ x$nrpcs != "x1" ]; then
15821                 $LCTL get_param osc.*.stats
15822                 error "found $nrpcs ost_write RPCs, not 1 as expected"
15823         fi
15824
15825         start_writeback
15826         # Drop the OSC cache, otherwise we will read from it
15827         cancel_lru_locks osc
15828
15829         # clear the OSC stats
15830         $LCTL set_param osc.*.stats=0 &>/dev/null
15831
15832         # Client reads $bulk_size.
15833         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
15834                 iflag=direct &>/dev/null || error "dd failed"
15835
15836         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
15837         if [ x$nrpcs != "x1" ]; then
15838                 $LCTL get_param osc.*.stats
15839                 error "found $nrpcs ost_read RPCs, not 1 as expected"
15840         fi
15841 }
15842 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
15843
15844 test_231b() {
15845         mkdir -p $DIR/$tdir
15846         local i
15847         for i in {0..1023}; do
15848                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
15849                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
15850                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
15851         done
15852         sync
15853 }
15854 run_test 231b "must not assert on fully utilized OST request buffer"
15855
15856 test_232a() {
15857         mkdir -p $DIR/$tdir
15858         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
15859
15860         #define OBD_FAIL_LDLM_OST_LVB            0x31c
15861         do_facet ost1 $LCTL set_param fail_loc=0x31c
15862
15863         # ignore dd failure
15864         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
15865
15866         do_facet ost1 $LCTL set_param fail_loc=0
15867         umount_client $MOUNT || error "umount failed"
15868         mount_client $MOUNT || error "mount failed"
15869         stop ost1 || error "cannot stop ost1"
15870         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
15871 }
15872 run_test 232a "failed lock should not block umount"
15873
15874 test_232b() {
15875         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
15876                 skip "Need MDS version at least 2.10.58"
15877
15878         mkdir -p $DIR/$tdir
15879         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
15880         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
15881         sync
15882         cancel_lru_locks osc
15883
15884         #define OBD_FAIL_LDLM_OST_LVB            0x31c
15885         do_facet ost1 $LCTL set_param fail_loc=0x31c
15886
15887         # ignore failure
15888         $LFS data_version $DIR/$tdir/$tfile || true
15889
15890         do_facet ost1 $LCTL set_param fail_loc=0
15891         umount_client $MOUNT || error "umount failed"
15892         mount_client $MOUNT || error "mount failed"
15893         stop ost1 || error "cannot stop ost1"
15894         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
15895 }
15896 run_test 232b "failed data version lock should not block umount"
15897
15898 test_233a() {
15899         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
15900                 skip "Need MDS version at least 2.3.64"
15901         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
15902
15903         local fid=$($LFS path2fid $MOUNT)
15904
15905         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15906                 error "cannot access $MOUNT using its FID '$fid'"
15907 }
15908 run_test 233a "checking that OBF of the FS root succeeds"
15909
15910 test_233b() {
15911         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
15912                 skip "Need MDS version at least 2.5.90"
15913         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
15914
15915         local fid=$($LFS path2fid $MOUNT/.lustre)
15916
15917         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15918                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
15919
15920         fid=$($LFS path2fid $MOUNT/.lustre/fid)
15921         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15922                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
15923 }
15924 run_test 233b "checking that OBF of the FS .lustre succeeds"
15925
15926 test_234() {
15927         local p="$TMP/sanityN-$TESTNAME.parameters"
15928         save_lustre_params client "llite.*.xattr_cache" > $p
15929         lctl set_param llite.*.xattr_cache 1 ||
15930                 skip_env "xattr cache is not supported"
15931
15932         mkdir -p $DIR/$tdir || error "mkdir failed"
15933         touch $DIR/$tdir/$tfile || error "touch failed"
15934         # OBD_FAIL_LLITE_XATTR_ENOMEM
15935         $LCTL set_param fail_loc=0x1405
15936         getfattr -n user.attr $DIR/$tdir/$tfile &&
15937                 error "getfattr should have failed with ENOMEM"
15938         $LCTL set_param fail_loc=0x0
15939         rm -rf $DIR/$tdir
15940
15941         restore_lustre_params < $p
15942         rm -f $p
15943 }
15944 run_test 234 "xattr cache should not crash on ENOMEM"
15945
15946 test_235() {
15947         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
15948                 skip "Need MDS version at least 2.4.52"
15949
15950         flock_deadlock $DIR/$tfile
15951         local RC=$?
15952         case $RC in
15953                 0)
15954                 ;;
15955                 124) error "process hangs on a deadlock"
15956                 ;;
15957                 *) error "error executing flock_deadlock $DIR/$tfile"
15958                 ;;
15959         esac
15960 }
15961 run_test 235 "LU-1715: flock deadlock detection does not work properly"
15962
15963 #LU-2935
15964 test_236() {
15965         check_swap_layouts_support
15966
15967         local ref1=/etc/passwd
15968         local ref2=/etc/group
15969         local file1=$DIR/$tdir/f1
15970         local file2=$DIR/$tdir/f2
15971
15972         test_mkdir -c1 $DIR/$tdir
15973         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
15974         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
15975         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
15976         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
15977         local fd=$(free_fd)
15978         local cmd="exec $fd<>$file2"
15979         eval $cmd
15980         rm $file2
15981         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
15982                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
15983         cmd="exec $fd>&-"
15984         eval $cmd
15985         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
15986
15987         #cleanup
15988         rm -rf $DIR/$tdir
15989 }
15990 run_test 236 "Layout swap on open unlinked file"
15991
15992 # LU-4659 linkea consistency
15993 test_238() {
15994         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15995                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15996                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15997                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15998
15999         touch $DIR/$tfile
16000         ln $DIR/$tfile $DIR/$tfile.lnk
16001         touch $DIR/$tfile.new
16002         mv $DIR/$tfile.new $DIR/$tfile
16003         local fid1=$($LFS path2fid $DIR/$tfile)
16004         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
16005         local path1=$($LFS fid2path $FSNAME "$fid1")
16006         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
16007         local path2=$($LFS fid2path $FSNAME "$fid2")
16008         [ $tfile.lnk == $path2 ] ||
16009                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
16010         rm -f $DIR/$tfile*
16011 }
16012 run_test 238 "Verify linkea consistency"
16013
16014 test_239A() { # was test_239
16015         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
16016                 skip "Need MDS version at least 2.5.60"
16017
16018         local list=$(comma_list $(mdts_nodes))
16019
16020         mkdir -p $DIR/$tdir
16021         createmany -o $DIR/$tdir/f- 5000
16022         unlinkmany $DIR/$tdir/f- 5000
16023         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
16024                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
16025         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
16026                         osp.*MDT*.sync_in_flight" | calc_sum)
16027         [ "$changes" -eq 0 ] || error "$changes not synced"
16028 }
16029 run_test 239A "osp_sync test"
16030
16031 test_239a() { #LU-5297
16032         remote_mds_nodsh && skip "remote MDS with nodsh"
16033
16034         touch $DIR/$tfile
16035         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
16036         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
16037         chgrp $RUNAS_GID $DIR/$tfile
16038         wait_delete_completed
16039 }
16040 run_test 239a "process invalid osp sync record correctly"
16041
16042 test_239b() { #LU-5297
16043         remote_mds_nodsh && skip "remote MDS with nodsh"
16044
16045         touch $DIR/$tfile1
16046         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
16047         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
16048         chgrp $RUNAS_GID $DIR/$tfile1
16049         wait_delete_completed
16050         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16051         touch $DIR/$tfile2
16052         chgrp $RUNAS_GID $DIR/$tfile2
16053         wait_delete_completed
16054 }
16055 run_test 239b "process osp sync record with ENOMEM error correctly"
16056
16057 test_240() {
16058         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16059         remote_mds_nodsh && skip "remote MDS with nodsh"
16060
16061         mkdir -p $DIR/$tdir
16062
16063         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
16064                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
16065         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
16066                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
16067
16068         umount_client $MOUNT || error "umount failed"
16069         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
16070         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
16071         mount_client $MOUNT || error "failed to mount client"
16072
16073         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
16074         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
16075 }
16076 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
16077
16078 test_241_bio() {
16079         local count=$1
16080         local bsize=$2
16081
16082         for LOOP in $(seq $count); do
16083                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
16084                 cancel_lru_locks $OSC || true
16085         done
16086 }
16087
16088 test_241_dio() {
16089         local count=$1
16090         local bsize=$2
16091
16092         for LOOP in $(seq $1); do
16093                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
16094                         2>/dev/null
16095         done
16096 }
16097
16098 test_241a() { # was test_241
16099         local bsize=$PAGE_SIZE
16100
16101         (( bsize < 40960 )) && bsize=40960
16102         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16103         ls -la $DIR/$tfile
16104         cancel_lru_locks $OSC
16105         test_241_bio 1000 $bsize &
16106         PID=$!
16107         test_241_dio 1000 $bsize
16108         wait $PID
16109 }
16110 run_test 241a "bio vs dio"
16111
16112 test_241b() {
16113         local bsize=$PAGE_SIZE
16114
16115         (( bsize < 40960 )) && bsize=40960
16116         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16117         ls -la $DIR/$tfile
16118         test_241_dio 1000 $bsize &
16119         PID=$!
16120         test_241_dio 1000 $bsize
16121         wait $PID
16122 }
16123 run_test 241b "dio vs dio"
16124
16125 test_242() {
16126         remote_mds_nodsh && skip "remote MDS with nodsh"
16127
16128         mkdir -p $DIR/$tdir
16129         touch $DIR/$tdir/$tfile
16130
16131         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
16132         do_facet mds1 lctl set_param fail_loc=0x105
16133         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
16134
16135         do_facet mds1 lctl set_param fail_loc=0
16136         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
16137 }
16138 run_test 242 "mdt_readpage failure should not cause directory unreadable"
16139
16140 test_243()
16141 {
16142         test_mkdir $DIR/$tdir
16143         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
16144 }
16145 run_test 243 "various group lock tests"
16146
16147 test_244()
16148 {
16149         test_mkdir $DIR/$tdir
16150         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
16151         sendfile_grouplock $DIR/$tdir/$tfile || \
16152                 error "sendfile+grouplock failed"
16153         rm -rf $DIR/$tdir
16154 }
16155 run_test 244 "sendfile with group lock tests"
16156
16157 test_245() {
16158         local flagname="multi_mod_rpcs"
16159         local connect_data_name="max_mod_rpcs"
16160         local out
16161
16162         # check if multiple modify RPCs flag is set
16163         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
16164                 grep "connect_flags:")
16165         echo "$out"
16166
16167         echo "$out" | grep -qw $flagname
16168         if [ $? -ne 0 ]; then
16169                 echo "connect flag $flagname is not set"
16170                 return
16171         fi
16172
16173         # check if multiple modify RPCs data is set
16174         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
16175         echo "$out"
16176
16177         echo "$out" | grep -qw $connect_data_name ||
16178                 error "import should have connect data $connect_data_name"
16179 }
16180 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
16181
16182 test_246() { # LU-7371
16183         remote_ost_nodsh && skip "remote OST with nodsh"
16184         [ $OST1_VERSION -lt $(version_code 2.7.62) ] &&
16185                 skip "Need OST version >= 2.7.62"
16186
16187         do_facet ost1 $LCTL set_param fail_val=4095
16188 #define OBD_FAIL_OST_READ_SIZE          0x234
16189         do_facet ost1 $LCTL set_param fail_loc=0x234
16190         $LFS setstripe $DIR/$tfile -i 0 -c 1
16191         dd if=/dev/zero of=$DIR/$tfile bs=4095 count=1 > /dev/null 2>&1
16192         cancel_lru_locks $FSNAME-OST0000
16193         dd if=$DIR/$tfile of=/dev/null bs=1048576 || error "Read failed"
16194 }
16195 run_test 246 "Read file of size 4095 should return right length"
16196
16197 cleanup_247() {
16198         local submount=$1
16199
16200         trap 0
16201         umount_client $submount
16202         rmdir $submount
16203 }
16204
16205 test_247a() {
16206         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16207                 grep -q subtree ||
16208                 skip_env "Fileset feature is not supported"
16209
16210         local submount=${MOUNT}_$tdir
16211
16212         mkdir $MOUNT/$tdir
16213         mkdir -p $submount || error "mkdir $submount failed"
16214         FILESET="$FILESET/$tdir" mount_client $submount ||
16215                 error "mount $submount failed"
16216         trap "cleanup_247 $submount" EXIT
16217         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
16218         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
16219                 error "read $MOUNT/$tdir/$tfile failed"
16220         cleanup_247 $submount
16221 }
16222 run_test 247a "mount subdir as fileset"
16223
16224 test_247b() {
16225         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16226                 skip_env "Fileset feature is not supported"
16227
16228         local submount=${MOUNT}_$tdir
16229
16230         rm -rf $MOUNT/$tdir
16231         mkdir -p $submount || error "mkdir $submount failed"
16232         SKIP_FILESET=1
16233         FILESET="$FILESET/$tdir" mount_client $submount &&
16234                 error "mount $submount should fail"
16235         rmdir $submount
16236 }
16237 run_test 247b "mount subdir that dose not exist"
16238
16239 test_247c() {
16240         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16241                 skip_env "Fileset feature is not supported"
16242
16243         local submount=${MOUNT}_$tdir
16244
16245         mkdir -p $MOUNT/$tdir/dir1
16246         mkdir -p $submount || error "mkdir $submount failed"
16247         trap "cleanup_247 $submount" EXIT
16248         FILESET="$FILESET/$tdir" mount_client $submount ||
16249                 error "mount $submount failed"
16250         local fid=$($LFS path2fid $MOUNT/)
16251         $LFS fid2path $submount $fid && error "fid2path should fail"
16252         cleanup_247 $submount
16253 }
16254 run_test 247c "running fid2path outside root"
16255
16256 test_247d() {
16257         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16258                 skip "Fileset feature is not supported"
16259
16260         local submount=${MOUNT}_$tdir
16261
16262         mkdir -p $MOUNT/$tdir/dir1
16263         mkdir -p $submount || error "mkdir $submount failed"
16264         FILESET="$FILESET/$tdir" mount_client $submount ||
16265                 error "mount $submount failed"
16266         trap "cleanup_247 $submount" EXIT
16267         local fid=$($LFS path2fid $submount/dir1)
16268         $LFS fid2path $submount $fid || error "fid2path should succeed"
16269         cleanup_247 $submount
16270 }
16271 run_test 247d "running fid2path inside root"
16272
16273 # LU-8037
16274 test_247e() {
16275         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16276                 grep -q subtree ||
16277                 skip "Fileset feature is not supported"
16278
16279         local submount=${MOUNT}_$tdir
16280
16281         mkdir $MOUNT/$tdir
16282         mkdir -p $submount || error "mkdir $submount failed"
16283         FILESET="$FILESET/.." mount_client $submount &&
16284                 error "mount $submount should fail"
16285         rmdir $submount
16286 }
16287 run_test 247e "mount .. as fileset"
16288
16289 test_248() {
16290         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
16291         [ -z "$fast_read_sav" ] && skip "no fast read support"
16292
16293         # create a large file for fast read verification
16294         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
16295
16296         # make sure the file is created correctly
16297         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
16298                 { rm -f $DIR/$tfile; skip "file creation error"; }
16299
16300         echo "Test 1: verify that fast read is 4 times faster on cache read"
16301
16302         # small read with fast read enabled
16303         $LCTL set_param -n llite.*.fast_read=1
16304         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16305                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16306                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16307         # small read with fast read disabled
16308         $LCTL set_param -n llite.*.fast_read=0
16309         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16310                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16311                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16312
16313         # verify that fast read is 4 times faster for cache read
16314         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
16315                 error_not_in_vm "fast read was not 4 times faster: " \
16316                            "$t_fast vs $t_slow"
16317
16318         echo "Test 2: verify the performance between big and small read"
16319         $LCTL set_param -n llite.*.fast_read=1
16320
16321         # 1k non-cache read
16322         cancel_lru_locks osc
16323         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16324                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16325                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16326
16327         # 1M non-cache read
16328         cancel_lru_locks osc
16329         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16330                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16331                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16332
16333         # verify that big IO is not 4 times faster than small IO
16334         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
16335                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
16336
16337         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
16338         rm -f $DIR/$tfile
16339 }
16340 run_test 248 "fast read verification"
16341
16342 test_249() { # LU-7890
16343         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
16344                 skip "Need at least version 2.8.54"
16345
16346         rm -f $DIR/$tfile
16347         $LFS setstripe -c 1 $DIR/$tfile
16348         # Offset 2T == 4k * 512M
16349         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
16350                 error "dd to 2T offset failed"
16351 }
16352 run_test 249 "Write above 2T file size"
16353
16354 test_250() {
16355         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
16356          && skip "no 16TB file size limit on ZFS"
16357
16358         $LFS setstripe -c 1 $DIR/$tfile
16359         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
16360         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
16361         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
16362         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
16363                 conv=notrunc,fsync && error "append succeeded"
16364         return 0
16365 }
16366 run_test 250 "Write above 16T limit"
16367
16368 test_251() {
16369         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
16370
16371         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
16372         #Skip once - writing the first stripe will succeed
16373         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16374         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
16375                 error "short write happened"
16376
16377         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16378         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
16379                 error "short read happened"
16380
16381         rm -f $DIR/$tfile
16382 }
16383 run_test 251 "Handling short read and write correctly"
16384
16385 test_252() {
16386         remote_mds_nodsh && skip "remote MDS with nodsh"
16387         remote_ost_nodsh && skip "remote OST with nodsh"
16388         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
16389                 skip_env "ldiskfs only test"
16390         fi
16391
16392         local tgt
16393         local dev
16394         local out
16395         local uuid
16396         local num
16397         local gen
16398
16399         # check lr_reader on OST0000
16400         tgt=ost1
16401         dev=$(facet_device $tgt)
16402         out=$(do_facet $tgt $LR_READER $dev)
16403         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16404         echo "$out"
16405         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
16406         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
16407                 error "Invalid uuid returned by $LR_READER on target $tgt"
16408         echo -e "uuid returned by $LR_READER is '$uuid'\n"
16409
16410         # check lr_reader -c on MDT0000
16411         tgt=mds1
16412         dev=$(facet_device $tgt)
16413         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
16414                 skip "$LR_READER does not support additional options"
16415         fi
16416         out=$(do_facet $tgt $LR_READER -c $dev)
16417         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16418         echo "$out"
16419         num=$(echo "$out" | grep -c "mdtlov")
16420         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
16421                 error "Invalid number of mdtlov clients returned by $LR_READER"
16422         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
16423
16424         # check lr_reader -cr on MDT0000
16425         out=$(do_facet $tgt $LR_READER -cr $dev)
16426         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16427         echo "$out"
16428         echo "$out" | grep -q "^reply_data:$" ||
16429                 error "$LR_READER should have returned 'reply_data' section"
16430         num=$(echo "$out" | grep -c "client_generation")
16431         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
16432 }
16433 run_test 252 "check lr_reader tool"
16434
16435 test_253_fill_ost() {
16436         local size_mb #how many MB should we write to pass watermark
16437         local lwm=$3  #low watermark
16438         local free_10mb #10% of free space
16439
16440         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16441         size_mb=$((free_kb / 1024 - lwm))
16442         free_10mb=$((free_kb / 10240))
16443         #If 10% of free space cross low watermark use it
16444         if (( free_10mb > size_mb )); then
16445                 size_mb=$free_10mb
16446         else
16447                 #At least we need to store 1.1 of difference between
16448                 #free space and low watermark
16449                 size_mb=$((size_mb + size_mb / 10))
16450         fi
16451         if (( lwm <= $((free_kb / 1024)) )) || [ ! -f $DIR/$tdir/1 ]; then
16452                 dd if=/dev/zero of=$DIR/$tdir/1 bs=1M count=$size_mb \
16453                          oflag=append conv=notrunc
16454         fi
16455
16456         sleep_maxage
16457
16458         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16459         echo "OST still has $((free_kb / 1024)) mbytes free"
16460 }
16461
16462 test_253() {
16463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16464         remote_mds_nodsh && skip "remote MDS with nodsh"
16465         remote_mgs_nodsh && skip "remote MGS with nodsh"
16466
16467         local ostidx=0
16468         local rc=0
16469
16470         local ost_name=$($LFS osts |
16471                 sed -n 's/^'$ostidx': \(.*\)_UUID .*/\1/p')
16472         # on the mdt's osc
16473         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
16474         do_facet $SINGLEMDS $LCTL get_param -n \
16475                 osp.$mdtosc_proc1.reserved_mb_high ||
16476                 skip  "remote MDS does not support reserved_mb_high"
16477
16478         rm -rf $DIR/$tdir
16479         wait_mds_ost_sync
16480         wait_delete_completed
16481         mkdir $DIR/$tdir
16482
16483         local last_wm_h=$(do_facet $SINGLEMDS $LCTL get_param -n \
16484                         osp.$mdtosc_proc1.reserved_mb_high)
16485         local last_wm_l=$(do_facet $SINGLEMDS $LCTL get_param -n \
16486                         osp.$mdtosc_proc1.reserved_mb_low)
16487         echo "prev high watermark $last_wm_h, prev low watermark $last_wm_l"
16488
16489         if ! combined_mgs_mds ; then
16490                 mount_mgs_client
16491         fi
16492         create_pool $FSNAME.$TESTNAME || error "Pool creation failed"
16493         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $ost_name ||
16494                 error "Adding $ost_name to pool failed"
16495
16496         # Wait for client to see a OST at pool
16497         wait_update $HOSTNAME "$LCTL get_param -n
16498                 lov.$FSNAME-*.pools.$TESTNAME | sort -u |
16499                 grep $ost_name" "$ost_name""_UUID" $((TIMEOUT/2)) ||
16500                 error "Client can not see the pool"
16501         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
16502                 error "Setstripe failed"
16503
16504         dd if=/dev/zero of=$DIR/$tdir/0 bs=1M count=10
16505         local blocks=$($LFS df $MOUNT | grep $ost_name | awk '{ print $4 }')
16506         echo "OST still has $((blocks/1024)) mbytes free"
16507
16508         local new_lwm=$((blocks/1024-10))
16509         do_facet $SINGLEMDS $LCTL set_param \
16510                         osp.$mdtosc_proc1.reserved_mb_high=$((new_lwm+5))
16511         do_facet $SINGLEMDS $LCTL set_param \
16512                         osp.$mdtosc_proc1.reserved_mb_low=$new_lwm
16513
16514         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16515
16516         #First enospc could execute orphan deletion so repeat.
16517         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16518
16519         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16520                         osp.$mdtosc_proc1.prealloc_status)
16521         echo "prealloc_status $oa_status"
16522
16523         dd if=/dev/zero of=$DIR/$tdir/2 bs=1M count=1 &&
16524                 error "File creation should fail"
16525         #object allocation was stopped, but we still able to append files
16526         dd if=/dev/zero of=$DIR/$tdir/1 bs=1M seek=6 count=5 oflag=append ||
16527                 error "Append failed"
16528         rm -f $DIR/$tdir/1 $DIR/$tdir/0 $DIR/$tdir/r*
16529
16530         wait_delete_completed
16531
16532         sleep_maxage
16533
16534         for i in $(seq 10 12); do
16535                 dd if=/dev/zero of=$DIR/$tdir/$i bs=1M count=1 2>/dev/null ||
16536                         error "File creation failed after rm";
16537         done
16538
16539         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16540                         osp.$mdtosc_proc1.prealloc_status)
16541         echo "prealloc_status $oa_status"
16542
16543         if (( oa_status != 0 )); then
16544                 error "Object allocation still disable after rm"
16545         fi
16546         do_facet $SINGLEMDS $LCTL set_param \
16547                         osp.$mdtosc_proc1.reserved_mb_high=$last_wm_h
16548         do_facet $SINGLEMDS $LCTL set_param \
16549                         osp.$mdtosc_proc1.reserved_mb_low=$last_wm_l
16550
16551
16552         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $ost_name ||
16553                 error "Remove $ost_name from pool failed"
16554         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
16555                 error "Pool destroy fialed"
16556
16557         if ! combined_mgs_mds ; then
16558                 umount_mgs_client
16559         fi
16560 }
16561 run_test 253 "Check object allocation limit"
16562
16563 test_254() {
16564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16565         remote_mds_nodsh && skip "remote MDS with nodsh"
16566         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
16567                 skip "MDS does not support changelog_size"
16568
16569         local cl_user
16570         local MDT0=$(facet_svc $SINGLEMDS)
16571
16572         changelog_register || error "changelog_register failed"
16573
16574         changelog_clear 0 || error "changelog_clear failed"
16575
16576         local size1=$(do_facet $SINGLEMDS \
16577                       $LCTL get_param -n mdd.$MDT0.changelog_size)
16578         echo "Changelog size $size1"
16579
16580         rm -rf $DIR/$tdir
16581         $LFS mkdir -i 0 $DIR/$tdir
16582         # change something
16583         mkdir -p $DIR/$tdir/pics/2008/zachy
16584         touch $DIR/$tdir/pics/2008/zachy/timestamp
16585         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
16586         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16587         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16588         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16589         rm $DIR/$tdir/pics/desktop.jpg
16590
16591         local size2=$(do_facet $SINGLEMDS \
16592                       $LCTL get_param -n mdd.$MDT0.changelog_size)
16593         echo "Changelog size after work $size2"
16594
16595         (( $size2 > $size1 )) ||
16596                 error "new Changelog size=$size2 less than old size=$size1"
16597 }
16598 run_test 254 "Check changelog size"
16599
16600 ladvise_no_type()
16601 {
16602         local type=$1
16603         local file=$2
16604
16605         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
16606                 awk -F: '{print $2}' | grep $type > /dev/null
16607         if [ $? -ne 0 ]; then
16608                 return 0
16609         fi
16610         return 1
16611 }
16612
16613 ladvise_no_ioctl()
16614 {
16615         local file=$1
16616
16617         lfs ladvise -a willread $file > /dev/null 2>&1
16618         if [ $? -eq 0 ]; then
16619                 return 1
16620         fi
16621
16622         lfs ladvise -a willread $file 2>&1 |
16623                 grep "Inappropriate ioctl for device" > /dev/null
16624         if [ $? -eq 0 ]; then
16625                 return 0
16626         fi
16627         return 1
16628 }
16629
16630 percent() {
16631         bc <<<"scale=2; ($1 - $2) * 100 / $2"
16632 }
16633
16634 # run a random read IO workload
16635 # usage: random_read_iops <filename> <filesize> <iosize>
16636 random_read_iops() {
16637         local file=$1
16638         local fsize=$2
16639         local iosize=${3:-4096}
16640
16641         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
16642                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
16643 }
16644
16645 drop_file_oss_cache() {
16646         local file="$1"
16647         local nodes="$2"
16648
16649         $LFS ladvise -a dontneed $file 2>/dev/null ||
16650                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
16651 }
16652
16653 ladvise_willread_performance()
16654 {
16655         local repeat=10
16656         local average_origin=0
16657         local average_cache=0
16658         local average_ladvise=0
16659
16660         for ((i = 1; i <= $repeat; i++)); do
16661                 echo "Iter $i/$repeat: reading without willread hint"
16662                 cancel_lru_locks osc
16663                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
16664                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
16665                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
16666                 average_origin=$(bc <<<"$average_origin + $speed_origin")
16667
16668                 cancel_lru_locks osc
16669                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
16670                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
16671                 average_cache=$(bc <<<"$average_cache + $speed_cache")
16672
16673                 cancel_lru_locks osc
16674                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
16675                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
16676                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
16677                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
16678                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
16679         done
16680         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
16681         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
16682         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
16683
16684         speedup_cache=$(percent $average_cache $average_origin)
16685         speedup_ladvise=$(percent $average_ladvise $average_origin)
16686
16687         echo "Average uncached read: $average_origin"
16688         echo "Average speedup with OSS cached read: " \
16689                 "$average_cache = +$speedup_cache%"
16690         echo "Average speedup with ladvise willread: " \
16691                 "$average_ladvise = +$speedup_ladvise%"
16692
16693         local lowest_speedup=20
16694         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
16695                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
16696                         "got $average_cache%. Skipping ladvise willread check."
16697                 return 0
16698         fi
16699
16700         # the test won't work on ZFS until it supports 'ladvise dontneed', but
16701         # it is still good to run until then to exercise 'ladvise willread'
16702         ! $LFS ladvise -a dontneed $DIR/$tfile &&
16703                 [ "$ost1_FSTYPE" = "zfs" ] &&
16704                 echo "osd-zfs does not support dontneed or drop_caches" &&
16705                 return 0
16706
16707         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
16708         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
16709                 error_not_in_vm "Speedup with willread is less than " \
16710                         "$lowest_speedup%, got $average_ladvise%"
16711 }
16712
16713 test_255a() {
16714         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
16715                 skip "lustre < 2.8.54 does not support ladvise "
16716         remote_ost_nodsh && skip "remote OST with nodsh"
16717
16718         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
16719
16720         ladvise_no_type willread $DIR/$tfile &&
16721                 skip "willread ladvise is not supported"
16722
16723         ladvise_no_ioctl $DIR/$tfile &&
16724                 skip "ladvise ioctl is not supported"
16725
16726         local size_mb=100
16727         local size=$((size_mb * 1048576))
16728         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
16729                 error "dd to $DIR/$tfile failed"
16730
16731         lfs ladvise -a willread $DIR/$tfile ||
16732                 error "Ladvise failed with no range argument"
16733
16734         lfs ladvise -a willread -s 0 $DIR/$tfile ||
16735                 error "Ladvise failed with no -l or -e argument"
16736
16737         lfs ladvise -a willread -e 1 $DIR/$tfile ||
16738                 error "Ladvise failed with only -e argument"
16739
16740         lfs ladvise -a willread -l 1 $DIR/$tfile ||
16741                 error "Ladvise failed with only -l argument"
16742
16743         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
16744                 error "End offset should not be smaller than start offset"
16745
16746         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
16747                 error "End offset should not be equal to start offset"
16748
16749         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
16750                 error "Ladvise failed with overflowing -s argument"
16751
16752         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
16753                 error "Ladvise failed with overflowing -e argument"
16754
16755         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
16756                 error "Ladvise failed with overflowing -l argument"
16757
16758         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
16759                 error "Ladvise succeeded with conflicting -l and -e arguments"
16760
16761         echo "Synchronous ladvise should wait"
16762         local delay=4
16763 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
16764         do_nodes $(comma_list $(osts_nodes)) \
16765                 $LCTL set_param fail_val=$delay fail_loc=0x237
16766
16767         local start_ts=$SECONDS
16768         lfs ladvise -a willread $DIR/$tfile ||
16769                 error "Ladvise failed with no range argument"
16770         local end_ts=$SECONDS
16771         local inteval_ts=$((end_ts - start_ts))
16772
16773         if [ $inteval_ts -lt $(($delay - 1)) ]; then
16774                 error "Synchronous advice didn't wait reply"
16775         fi
16776
16777         echo "Asynchronous ladvise shouldn't wait"
16778         local start_ts=$SECONDS
16779         lfs ladvise -a willread -b $DIR/$tfile ||
16780                 error "Ladvise failed with no range argument"
16781         local end_ts=$SECONDS
16782         local inteval_ts=$((end_ts - start_ts))
16783
16784         if [ $inteval_ts -gt $(($delay / 2)) ]; then
16785                 error "Asynchronous advice blocked"
16786         fi
16787
16788         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
16789         ladvise_willread_performance
16790 }
16791 run_test 255a "check 'lfs ladvise -a willread'"
16792
16793 facet_meminfo() {
16794         local facet=$1
16795         local info=$2
16796
16797         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
16798 }
16799
16800 test_255b() {
16801         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
16802                 skip "lustre < 2.8.54 does not support ladvise "
16803         remote_ost_nodsh && skip "remote OST with nodsh"
16804
16805         lfs setstripe -c 1 -i 0 $DIR/$tfile
16806
16807         ladvise_no_type dontneed $DIR/$tfile &&
16808                 skip "dontneed ladvise is not supported"
16809
16810         ladvise_no_ioctl $DIR/$tfile &&
16811                 skip "ladvise ioctl is not supported"
16812
16813         ! $LFS ladvise -a dontneed $DIR/$tfile &&
16814                 [ "$ost1_FSTYPE" = "zfs" ] &&
16815                 skip "zfs-osd does not support 'ladvise dontneed'"
16816
16817         local size_mb=100
16818         local size=$((size_mb * 1048576))
16819         # In order to prevent disturbance of other processes, only check 3/4
16820         # of the memory usage
16821         local kibibytes=$((size_mb * 1024 * 3 / 4))
16822
16823         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
16824                 error "dd to $DIR/$tfile failed"
16825
16826         #force write to complete before dropping OST cache & checking memory
16827         sync
16828
16829         local total=$(facet_meminfo ost1 MemTotal)
16830         echo "Total memory: $total KiB"
16831
16832         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
16833         local before_read=$(facet_meminfo ost1 Cached)
16834         echo "Cache used before read: $before_read KiB"
16835
16836         lfs ladvise -a willread $DIR/$tfile ||
16837                 error "Ladvise willread failed"
16838         local after_read=$(facet_meminfo ost1 Cached)
16839         echo "Cache used after read: $after_read KiB"
16840
16841         lfs ladvise -a dontneed $DIR/$tfile ||
16842                 error "Ladvise dontneed again failed"
16843         local no_read=$(facet_meminfo ost1 Cached)
16844         echo "Cache used after dontneed ladvise: $no_read KiB"
16845
16846         if [ $total -lt $((before_read + kibibytes)) ]; then
16847                 echo "Memory is too small, abort checking"
16848                 return 0
16849         fi
16850
16851         if [ $((before_read + kibibytes)) -gt $after_read ]; then
16852                 error "Ladvise willread should use more memory" \
16853                         "than $kibibytes KiB"
16854         fi
16855
16856         if [ $((no_read + kibibytes)) -gt $after_read ]; then
16857                 error "Ladvise dontneed should release more memory" \
16858                         "than $kibibytes KiB"
16859         fi
16860 }
16861 run_test 255b "check 'lfs ladvise -a dontneed'"
16862
16863 test_255c() {
16864         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
16865                 skip "lustre < 2.10.53 does not support lockahead"
16866
16867         local count
16868         local new_count
16869         local difference
16870         local i
16871         local rc
16872
16873         test_mkdir -p $DIR/$tdir
16874         $LFS setstripe -i 0 -c 1 $DIR/$tdir
16875
16876         #test 10 returns only success/failure
16877         i=10
16878         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16879         rc=$?
16880         if [ $rc -eq 255 ]; then
16881                 error "Ladvise test${i} failed, ${rc}"
16882         fi
16883
16884         #test 11 counts lock enqueue requests, all others count new locks
16885         i=11
16886         count=$(do_facet ost1 \
16887                 $LCTL get_param -n ost.OSS.ost.stats)
16888         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
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=$(do_facet ost1 \
16897                 $LCTL get_param -n ost.OSS.ost.stats)
16898         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
16899                    awk '{ print $2 }')
16900
16901         difference="$((new_count - count))"
16902         if [ $difference -ne $rc ]; then
16903                 error "Ladvise test${i}, bad enqueue count, returned " \
16904                       "${rc}, actual ${difference}"
16905         fi
16906
16907         for i in $(seq 12 21); do
16908                 # If we do not do this, we run the risk of having too many
16909                 # locks and starting lock cancellation while we are checking
16910                 # lock counts.
16911                 cancel_lru_locks osc
16912
16913                 count=$($LCTL get_param -n \
16914                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
16915
16916                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
16917                 rc=$?
16918                 if [ $rc -eq 255 ]; then
16919                         error "Ladvise test ${i} failed, ${rc}"
16920                 fi
16921
16922                 new_count=$($LCTL get_param -n \
16923                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
16924                 difference="$((new_count - count))"
16925
16926                 # Test 15 output is divided by 100 to map down to valid return
16927                 if [ $i -eq 15 ]; then
16928                         rc="$((rc * 100))"
16929                 fi
16930
16931                 if [ $difference -ne $rc ]; then
16932                         error "Ladvise test ${i}, bad lock count, returned " \
16933                               "${rc}, actual ${difference}"
16934                 fi
16935         done
16936
16937         #test 22 returns only success/failure
16938         i=22
16939         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16940         rc=$?
16941         if [ $rc -eq 255 ]; then
16942                 error "Ladvise test${i} failed, ${rc}"
16943         fi
16944 }
16945 run_test 255c "suite of ladvise lockahead tests"
16946
16947 test_256() {
16948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16949         remote_mds_nodsh && skip "remote MDS with nodsh"
16950         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
16951         changelog_users $SINGLEMDS | grep "^cl" &&
16952                 skip "active changelog user"
16953
16954         local cl_user
16955         local cat_sl
16956         local mdt_dev
16957
16958         mdt_dev=$(mdsdevname 1)
16959         echo $mdt_dev
16960
16961         changelog_register || error "changelog_register failed"
16962
16963         rm -rf $DIR/$tdir
16964         mkdir -p $DIR/$tdir
16965
16966         changelog_clear 0 || error "changelog_clear failed"
16967
16968         # change something
16969         touch $DIR/$tdir/{1..10}
16970
16971         # stop the MDT
16972         stop $SINGLEMDS || error "Fail to stop MDT"
16973
16974         # remount the MDT
16975
16976         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
16977
16978         #after mount new plainllog is used
16979         touch $DIR/$tdir/{11..19}
16980         local tmpfile=$(mktemp -u $tfile.XXXXXX)
16981         cat_sl=$(do_facet $SINGLEMDS "sync; \
16982                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
16983                  llog_reader $tmpfile | grep -c type=1064553b")
16984         do_facet $SINGLEMDS llog_reader $tmpfile
16985
16986         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
16987
16988         changelog_clear 0 || error "changelog_clear failed"
16989
16990         cat_sl=$(do_facet $SINGLEMDS "sync; \
16991                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
16992                  llog_reader $tmpfile | grep -c type=1064553b; rm -f $tmpfile")
16993
16994         if (( cat_sl == 2 )); then
16995                 error "Empty plain llog was not deleted from changelog catalog"
16996         elif (( cat_sl != 1 )); then
16997                 error "Active plain llog shouldn't be deleted from catalog"
16998         fi
16999 }
17000 run_test 256 "Check llog delete for empty and not full state"
17001
17002 test_257() {
17003         remote_mds_nodsh && skip "remote MDS with nodsh"
17004         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
17005                 skip "Need MDS version at least 2.8.55"
17006
17007         test_mkdir $DIR/$tdir
17008
17009         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
17010                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
17011         stat $DIR/$tdir
17012
17013 #define OBD_FAIL_MDS_XATTR_REP                  0x161
17014         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17015         local facet=mds$((mdtidx + 1))
17016         set_nodes_failloc $(facet_active_host $facet) 0x80000161
17017         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
17018
17019         stop $facet || error "stop MDS failed"
17020         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
17021                 error "start MDS fail"
17022         wait_recovery_complete $facet
17023 }
17024 run_test 257 "xattr locks are not lost"
17025
17026 # Verify we take the i_mutex when security requires it
17027 test_258a() {
17028 #define OBD_FAIL_IMUTEX_SEC 0x141c
17029         $LCTL set_param fail_loc=0x141c
17030         touch $DIR/$tfile
17031         chmod u+s $DIR/$tfile
17032         chmod a+rwx $DIR/$tfile
17033         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17034         RC=$?
17035         if [ $RC -ne 0 ]; then
17036                 error "error, failed to take i_mutex, rc=$?"
17037         fi
17038         rm -f $DIR/$tfile
17039 }
17040 run_test 258a
17041
17042 # Verify we do NOT take the i_mutex in the normal case
17043 test_258b() {
17044 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
17045         $LCTL set_param fail_loc=0x141d
17046         touch $DIR/$tfile
17047         chmod a+rwx $DIR
17048         chmod a+rw $DIR/$tfile
17049         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17050         RC=$?
17051         if [ $RC -ne 0 ]; then
17052                 error "error, took i_mutex unnecessarily, rc=$?"
17053         fi
17054         rm -f $DIR/$tfile
17055
17056 }
17057 run_test 258b "verify i_mutex security behavior"
17058
17059 test_259() {
17060         local file=$DIR/$tfile
17061         local before
17062         local after
17063
17064         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17065
17066         stack_trap "rm -f $file" EXIT
17067
17068         wait_delete_completed
17069         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17070         echo "before: $before"
17071
17072         $LFS setstripe -i 0 -c 1 $file
17073         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
17074         sync_all_data
17075         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17076         echo "after write: $after"
17077
17078 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
17079         do_facet ost1 $LCTL set_param fail_loc=0x2301
17080         $TRUNCATE $file 0
17081         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17082         echo "after truncate: $after"
17083
17084         stop ost1
17085         do_facet ost1 $LCTL set_param fail_loc=0
17086         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17087         sleep 2
17088         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17089         echo "after restart: $after"
17090         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
17091                 error "missing truncate?"
17092
17093         return 0
17094 }
17095 run_test 259 "crash at delayed truncate"
17096
17097 test_260() {
17098 #define OBD_FAIL_MDC_CLOSE               0x806
17099         $LCTL set_param fail_loc=0x80000806
17100         touch $DIR/$tfile
17101
17102 }
17103 run_test 260 "Check mdc_close fail"
17104
17105 ### Data-on-MDT sanity tests ###
17106 test_270a() {
17107         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17108                 skip "Need MDS version at least 2.10.55 for DoM"
17109
17110         # create DoM file
17111         local dom=$DIR/$tdir/dom_file
17112         local tmp=$DIR/$tdir/tmp_file
17113
17114         mkdir -p $DIR/$tdir
17115
17116         # basic checks for DoM component creation
17117         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
17118                 error "Can set MDT layout to non-first entry"
17119
17120         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
17121                 error "Can define multiple entries as MDT layout"
17122
17123         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
17124
17125         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
17126         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
17127         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
17128
17129         local mdtidx=$($LFS getstripe -m $dom)
17130         local mdtname=MDT$(printf %04x $mdtidx)
17131         local facet=mds$((mdtidx + 1))
17132         local space_check=1
17133
17134         # Skip free space checks with ZFS
17135         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
17136
17137         # write
17138         sync
17139         local size_tmp=$((65536 * 3))
17140         local mdtfree1=$(do_facet $facet \
17141                          lctl get_param -n osd*.*$mdtname.kbytesfree)
17142
17143         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17144         # check also direct IO along write
17145         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
17146         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17147         sync
17148         cmp $tmp $dom || error "file data is different"
17149         [ $(stat -c%s $dom) == $size_tmp ] ||
17150                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17151         if [ $space_check == 1 ]; then
17152                 local mdtfree2=$(do_facet $facet \
17153                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
17154
17155                 # increase in usage from by $size_tmp
17156                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17157                         error "MDT free space wrong after write: " \
17158                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17159         fi
17160
17161         # truncate
17162         local size_dom=10000
17163
17164         $TRUNCATE $dom $size_dom
17165         [ $(stat -c%s $dom) == $size_dom ] ||
17166                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
17167         if [ $space_check == 1 ]; then
17168                 mdtfree1=$(do_facet $facet \
17169                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17170                 # decrease in usage from $size_tmp to new $size_dom
17171                 [ $(($mdtfree1 - $mdtfree2)) -ge \
17172                   $(((size_tmp - size_dom) / 1024)) ] ||
17173                         error "MDT free space is wrong after truncate: " \
17174                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
17175         fi
17176
17177         # append
17178         cat $tmp >> $dom
17179         sync
17180         size_dom=$((size_dom + size_tmp))
17181         [ $(stat -c%s $dom) == $size_dom ] ||
17182                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
17183         if [ $space_check == 1 ]; then
17184                 mdtfree2=$(do_facet $facet \
17185                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17186                 # increase in usage by $size_tmp from previous
17187                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17188                         error "MDT free space is wrong after append: " \
17189                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17190         fi
17191
17192         # delete
17193         rm $dom
17194         if [ $space_check == 1 ]; then
17195                 mdtfree1=$(do_facet $facet \
17196                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17197                 # decrease in usage by $size_dom from previous
17198                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
17199                         error "MDT free space is wrong after removal: " \
17200                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
17201         fi
17202
17203         # combined striping
17204         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
17205                 error "Can't create DoM + OST striping"
17206
17207         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
17208         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17209         # check also direct IO along write
17210         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17211         sync
17212         cmp $tmp $dom || error "file data is different"
17213         [ $(stat -c%s $dom) == $size_tmp ] ||
17214                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17215         rm $dom $tmp
17216
17217         return 0
17218 }
17219 run_test 270a "DoM: basic functionality tests"
17220
17221 test_270b() {
17222         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17223                 skip "Need MDS version at least 2.10.55"
17224
17225         local dom=$DIR/$tdir/dom_file
17226         local max_size=1048576
17227
17228         mkdir -p $DIR/$tdir
17229         $LFS setstripe -E $max_size -L mdt $dom
17230
17231         # truncate over the limit
17232         $TRUNCATE $dom $(($max_size + 1)) &&
17233                 error "successful truncate over the maximum size"
17234         # write over the limit
17235         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
17236                 error "successful write over the maximum size"
17237         # append over the limit
17238         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
17239         echo "12345" >> $dom && error "successful append over the maximum size"
17240         rm $dom
17241
17242         return 0
17243 }
17244 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
17245
17246 test_270c() {
17247         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17248                 skip "Need MDS version at least 2.10.55"
17249
17250         mkdir -p $DIR/$tdir
17251         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17252
17253         # check files inherit DoM EA
17254         touch $DIR/$tdir/first
17255         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
17256                 error "bad pattern"
17257         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
17258                 error "bad stripe count"
17259         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
17260                 error "bad stripe size"
17261
17262         # check directory inherits DoM EA and uses it as default
17263         mkdir $DIR/$tdir/subdir
17264         touch $DIR/$tdir/subdir/second
17265         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
17266                 error "bad pattern in sub-directory"
17267         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
17268                 error "bad stripe count in sub-directory"
17269         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
17270                 error "bad stripe size in sub-directory"
17271         return 0
17272 }
17273 run_test 270c "DoM: DoM EA inheritance tests"
17274
17275 test_270d() {
17276         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17277                 skip "Need MDS version at least 2.10.55"
17278
17279         mkdir -p $DIR/$tdir
17280         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17281
17282         # inherit default DoM striping
17283         mkdir $DIR/$tdir/subdir
17284         touch $DIR/$tdir/subdir/f1
17285
17286         # change default directory striping
17287         $LFS setstripe -c 1 $DIR/$tdir/subdir
17288         touch $DIR/$tdir/subdir/f2
17289         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
17290                 error "wrong default striping in file 2"
17291         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
17292                 error "bad pattern in file 2"
17293         return 0
17294 }
17295 run_test 270d "DoM: change striping from DoM to RAID0"
17296
17297 test_270e() {
17298         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17299                 skip "Need MDS version at least 2.10.55"
17300
17301         mkdir -p $DIR/$tdir/dom
17302         mkdir -p $DIR/$tdir/norm
17303         DOMFILES=20
17304         NORMFILES=10
17305         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
17306         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
17307
17308         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
17309         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
17310
17311         # find DoM files by layout
17312         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
17313         [ $NUM -eq  $DOMFILES ] ||
17314                 error "lfs find -L: found $NUM, expected $DOMFILES"
17315         echo "Test 1: lfs find 20 DOM files by layout: OK"
17316
17317         # there should be 1 dir with default DOM striping
17318         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
17319         [ $NUM -eq  1 ] ||
17320                 error "lfs find -L: found $NUM, expected 1 dir"
17321         echo "Test 2: lfs find 1 DOM dir by layout: OK"
17322
17323         # find DoM files by stripe size
17324         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
17325         [ $NUM -eq  $DOMFILES ] ||
17326                 error "lfs find -S: found $NUM, expected $DOMFILES"
17327         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
17328
17329         # find files by stripe offset except DoM files
17330         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
17331         [ $NUM -eq  $NORMFILES ] ||
17332                 error "lfs find -i: found $NUM, expected $NORMFILES"
17333         echo "Test 5: lfs find no DOM files by stripe index: OK"
17334         return 0
17335 }
17336 run_test 270e "DoM: lfs find with DoM files test"
17337
17338 test_270f() {
17339         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17340                 skip "Need MDS version at least 2.10.55"
17341
17342         local mdtname=${FSNAME}-MDT0000-mdtlov
17343         local dom=$DIR/$tdir/dom_file
17344         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
17345                                                 lod.$mdtname.dom_stripesize)
17346         local dom_limit=131072
17347
17348         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
17349         local dom_current=$(do_facet mds1 $LCTL get_param -n \
17350                                                 lod.$mdtname.dom_stripesize)
17351         [ ${dom_limit} -eq ${dom_current} ] ||
17352                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
17353
17354         $LFS mkdir -i 0 -c 1 $DIR/$tdir
17355         $LFS setstripe -d $DIR/$tdir
17356         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
17357                 error "Can't set directory default striping"
17358
17359         # exceed maximum stripe size
17360         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17361                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
17362         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
17363                 error "Able to create DoM component size more than LOD limit"
17364
17365         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
17366         dom_current=$(do_facet mds1 $LCTL get_param -n \
17367                                                 lod.$mdtname.dom_stripesize)
17368         [ 0 -eq ${dom_current} ] ||
17369                 error "Can't set zero DoM stripe limit"
17370         rm $dom
17371
17372         # attempt to create DoM file on server with disabled DoM should
17373         # remove DoM entry from layout and be succeed
17374         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
17375                 error "Can't create DoM file (DoM is disabled)"
17376         [ $($LFS getstripe -L $dom) == "mdt" ] &&
17377                 error "File has DoM component while DoM is disabled"
17378         rm $dom
17379
17380         # attempt to create DoM file with only DoM stripe should return error
17381         $LFS setstripe -E $dom_limit -L mdt $dom &&
17382                 error "Able to create DoM-only file while DoM is disabled"
17383
17384         # too low values to be aligned with smallest stripe size 64K
17385         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
17386         dom_current=$(do_facet mds1 $LCTL get_param -n \
17387                                                 lod.$mdtname.dom_stripesize)
17388         [ 30000 -eq ${dom_current} ] &&
17389                 error "Can set too small DoM stripe limit"
17390
17391         # 64K is a minimal stripe size in Lustre, expect limit of that size
17392         [ 65536 -eq ${dom_current} ] ||
17393                 error "Limit is not set to 64K but ${dom_current}"
17394
17395         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
17396         dom_current=$(do_facet mds1 $LCTL get_param -n \
17397                                                 lod.$mdtname.dom_stripesize)
17398         echo $dom_current
17399         [ 2147483648 -eq ${dom_current} ] &&
17400                 error "Can set too large DoM stripe limit"
17401
17402         do_facet mds1 $LCTL set_param -n \
17403                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
17404         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17405                 error "Can't create DoM component size after limit change"
17406         do_facet mds1 $LCTL set_param -n \
17407                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
17408         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
17409                 error "Can't create DoM file after limit decrease"
17410         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
17411                 error "Can create big DoM component after limit decrease"
17412         touch ${dom}_def ||
17413                 error "Can't create file with old default layout"
17414
17415         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
17416         return 0
17417 }
17418 run_test 270f "DoM: maximum DoM stripe size checks"
17419
17420 test_271a() {
17421         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17422                 skip "Need MDS version at least 2.10.55"
17423
17424         local dom=$DIR/$tdir/dom
17425
17426         mkdir -p $DIR/$tdir
17427
17428         $LFS setstripe -E 1024K -L mdt $dom
17429
17430         lctl set_param -n mdc.*.stats=clear
17431         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17432         cat $dom > /dev/null
17433         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
17434         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
17435         ls $dom
17436         rm -f $dom
17437 }
17438 run_test 271a "DoM: data is cached for read after write"
17439
17440 test_271b() {
17441         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17442                 skip "Need MDS version at least 2.10.55"
17443
17444         local dom=$DIR/$tdir/dom
17445
17446         mkdir -p $DIR/$tdir
17447
17448         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17449
17450         lctl set_param -n mdc.*.stats=clear
17451         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17452         cancel_lru_locks mdc
17453         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
17454         # second stat to check size is cached on client
17455         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
17456         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17457         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
17458         rm -f $dom
17459 }
17460 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
17461
17462 test_271ba() {
17463         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17464                 skip "Need MDS version at least 2.10.55"
17465
17466         local dom=$DIR/$tdir/dom
17467
17468         mkdir -p $DIR/$tdir
17469
17470         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17471
17472         lctl set_param -n mdc.*.stats=clear
17473         lctl set_param -n osc.*.stats=clear
17474         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
17475         cancel_lru_locks mdc
17476         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17477         # second stat to check size is cached on client
17478         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17479         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17480         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
17481         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
17482         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
17483         rm -f $dom
17484 }
17485 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
17486
17487
17488 get_mdc_stats() {
17489         local mdtidx=$1
17490         local param=$2
17491         local mdt=MDT$(printf %04x $mdtidx)
17492
17493         if [ -z $param ]; then
17494                 lctl get_param -n mdc.*$mdt*.stats
17495         else
17496                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
17497         fi
17498 }
17499
17500 test_271c() {
17501         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17502                 skip "Need MDS version at least 2.10.55"
17503
17504         local dom=$DIR/$tdir/dom
17505
17506         mkdir -p $DIR/$tdir
17507
17508         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17509
17510         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17511         local facet=mds$((mdtidx + 1))
17512
17513         cancel_lru_locks mdc
17514         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
17515         createmany -o $dom 1000
17516         lctl set_param -n mdc.*.stats=clear
17517         smalliomany -w $dom 1000 200
17518         get_mdc_stats $mdtidx
17519         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17520         # Each file has 1 open, 1 IO enqueues, total 2000
17521         # but now we have also +1 getxattr for security.capability, total 3000
17522         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
17523         unlinkmany $dom 1000
17524
17525         cancel_lru_locks mdc
17526         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
17527         createmany -o $dom 1000
17528         lctl set_param -n mdc.*.stats=clear
17529         smalliomany -w $dom 1000 200
17530         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17531         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
17532         # for OPEN and IO lock.
17533         [ $((enq - enq_2)) -ge 1000 ] ||
17534                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
17535         unlinkmany $dom 1000
17536         return 0
17537 }
17538 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
17539
17540 cleanup_271def_tests() {
17541         trap 0
17542         rm -f $1
17543 }
17544
17545 test_271d() {
17546         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17547                 skip "Need MDS version at least 2.10.57"
17548
17549         local dom=$DIR/$tdir/dom
17550         local tmp=$TMP/$tfile
17551         trap "cleanup_271def_tests $tmp" EXIT
17552
17553         mkdir -p $DIR/$tdir
17554
17555         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17556
17557         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17558
17559         cancel_lru_locks mdc
17560         dd if=/dev/urandom of=$tmp bs=1000 count=1
17561         dd if=$tmp of=$dom bs=1000 count=1
17562         cancel_lru_locks mdc
17563
17564         cat /etc/hosts >> $tmp
17565         lctl set_param -n mdc.*.stats=clear
17566
17567         # append data to the same file it should update local page
17568         echo "Append to the same page"
17569         cat /etc/hosts >> $dom
17570         local num=$(get_mdc_stats $mdtidx ost_read)
17571         local ra=$(get_mdc_stats $mdtidx req_active)
17572         local rw=$(get_mdc_stats $mdtidx req_waittime)
17573
17574         [ -z $num ] || error "$num READ RPC occured"
17575         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17576         echo "... DONE"
17577
17578         # compare content
17579         cmp $tmp $dom || error "file miscompare"
17580
17581         cancel_lru_locks mdc
17582         lctl set_param -n mdc.*.stats=clear
17583
17584         echo "Open and read file"
17585         cat $dom > /dev/null
17586         local num=$(get_mdc_stats $mdtidx ost_read)
17587         local ra=$(get_mdc_stats $mdtidx req_active)
17588         local rw=$(get_mdc_stats $mdtidx req_waittime)
17589
17590         [ -z $num ] || error "$num READ RPC occured"
17591         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17592         echo "... DONE"
17593
17594         # compare content
17595         cmp $tmp $dom || error "file miscompare"
17596
17597         return 0
17598 }
17599 run_test 271d "DoM: read on open (1K file in reply buffer)"
17600
17601 test_271f() {
17602         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17603                 skip "Need MDS version at least 2.10.57"
17604
17605         local dom=$DIR/$tdir/dom
17606         local tmp=$TMP/$tfile
17607         trap "cleanup_271def_tests $tmp" EXIT
17608
17609         mkdir -p $DIR/$tdir
17610
17611         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17612
17613         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17614
17615         cancel_lru_locks mdc
17616         dd if=/dev/urandom of=$tmp bs=200000 count=1
17617         dd if=$tmp of=$dom bs=200000 count=1
17618         cancel_lru_locks mdc
17619         cat /etc/hosts >> $tmp
17620         lctl set_param -n mdc.*.stats=clear
17621
17622         echo "Append to the same page"
17623         cat /etc/hosts >> $dom
17624         local num=$(get_mdc_stats $mdtidx ost_read)
17625         local ra=$(get_mdc_stats $mdtidx req_active)
17626         local rw=$(get_mdc_stats $mdtidx req_waittime)
17627
17628         [ -z $num ] || error "$num READ RPC occured"
17629         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17630         echo "... DONE"
17631
17632         # compare content
17633         cmp $tmp $dom || error "file miscompare"
17634
17635         cancel_lru_locks mdc
17636         lctl set_param -n mdc.*.stats=clear
17637
17638         echo "Open and read file"
17639         cat $dom > /dev/null
17640         local num=$(get_mdc_stats $mdtidx ost_read)
17641         local ra=$(get_mdc_stats $mdtidx req_active)
17642         local rw=$(get_mdc_stats $mdtidx req_waittime)
17643
17644         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
17645         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17646         echo "... DONE"
17647
17648         # compare content
17649         cmp $tmp $dom || error "file miscompare"
17650
17651         return 0
17652 }
17653 run_test 271f "DoM: read on open (200K file and read tail)"
17654
17655 test_272a() {
17656         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17657                 skip "Need MDS version at least 2.11.50"
17658
17659         local dom=$DIR/$tdir/dom
17660         mkdir -p $DIR/$tdir
17661
17662         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
17663         dd if=/dev/urandom of=$dom bs=512K count=1 ||
17664                 error "failed to write data into $dom"
17665         local old_md5=$(md5sum $dom)
17666
17667         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
17668                 error "failed to migrate to the same DoM component"
17669
17670         local new_md5=$(md5sum $dom)
17671
17672         [ "$old_md5" == "$new_md5" ] ||
17673                 error "md5sum differ: $old_md5, $new_md5"
17674
17675         [ $($LFS getstripe -c $dom) -eq 2 ] ||
17676                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
17677 }
17678 run_test 272a "DoM migration: new layout with the same DOM component"
17679
17680 test_272b() {
17681         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17682                 skip "Need MDS version at least 2.11.50"
17683
17684         local dom=$DIR/$tdir/dom
17685         mkdir -p $DIR/$tdir
17686         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
17687
17688         local mdtidx=$($LFS getstripe -m $dom)
17689         local mdtname=MDT$(printf %04x $mdtidx)
17690         local facet=mds$((mdtidx + 1))
17691
17692         local mdtfree1=$(do_facet $facet \
17693                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17694         dd if=/dev/urandom of=$dom bs=2M count=1 ||
17695                 error "failed to write data into $dom"
17696         local old_md5=$(md5sum $dom)
17697         cancel_lru_locks mdc
17698         local mdtfree1=$(do_facet $facet \
17699                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17700
17701         $LFS migrate -c2 $dom ||
17702                 error "failed to migrate to the new composite layout"
17703         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
17704                 error "MDT stripe was not removed"
17705
17706         cancel_lru_locks mdc
17707         local new_md5=$(md5sum $dom)
17708         [ "$old_md5" != "$new_md5" ] &&
17709                 error "$old_md5 != $new_md5"
17710
17711         # Skip free space checks with ZFS
17712         if [ "$(facet_fstype $facet)" != "zfs" ]; then
17713                 local mdtfree2=$(do_facet $facet \
17714                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17715                 [ $mdtfree2 -gt $mdtfree1 ] ||
17716                         error "MDT space is not freed after migration"
17717         fi
17718         return 0
17719 }
17720 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
17721
17722 test_272c() {
17723         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17724                 skip "Need MDS version at least 2.11.50"
17725
17726         local dom=$DIR/$tdir/$tfile
17727         mkdir -p $DIR/$tdir
17728         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
17729
17730         local mdtidx=$($LFS getstripe -m $dom)
17731         local mdtname=MDT$(printf %04x $mdtidx)
17732         local facet=mds$((mdtidx + 1))
17733
17734         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
17735                 error "failed to write data into $dom"
17736         local old_md5=$(md5sum $dom)
17737         cancel_lru_locks mdc
17738         local mdtfree1=$(do_facet $facet \
17739                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17740
17741         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
17742                 error "failed to migrate to the new composite layout"
17743         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
17744                 error "MDT stripe was not removed"
17745
17746         cancel_lru_locks mdc
17747         local new_md5=$(md5sum $dom)
17748         [ "$old_md5" != "$new_md5" ] &&
17749                 error "$old_md5 != $new_md5"
17750
17751         # Skip free space checks with ZFS
17752         if [ "$(facet_fstype $facet)" != "zfs" ]; then
17753                 local mdtfree2=$(do_facet $facet \
17754                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17755                 [ $mdtfree2 -gt $mdtfree1 ] ||
17756                         error "MDS space is not freed after migration"
17757         fi
17758         return 0
17759 }
17760 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
17761
17762 test_273a() {
17763         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17764                 skip "Need MDS version at least 2.11.50"
17765
17766         # Layout swap cannot be done if either file has DOM component,
17767         # this will never be supported, migration should be used instead
17768
17769         local dom=$DIR/$tdir/$tfile
17770         mkdir -p $DIR/$tdir
17771
17772         $LFS setstripe -c2 ${dom}_plain
17773         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
17774         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
17775                 error "can swap layout with DoM component"
17776         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
17777                 error "can swap layout with DoM component"
17778
17779         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
17780         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
17781                 error "can swap layout with DoM component"
17782         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
17783                 error "can swap layout with DoM component"
17784         return 0
17785 }
17786 run_test 273a "DoM: layout swapping should fail with DOM"
17787
17788 test_275() {
17789         remote_ost_nodsh && skip "remote OST with nodsh"
17790         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
17791                 skip "Need OST version >= 2.10.57"
17792
17793         local file=$DIR/$tfile
17794         local oss
17795
17796         oss=$(comma_list $(osts_nodes))
17797
17798         dd if=/dev/urandom of=$file bs=1M count=2 ||
17799                 error "failed to create a file"
17800         cancel_lru_locks osc
17801
17802         #lock 1
17803         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
17804                 error "failed to read a file"
17805
17806 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
17807         $LCTL set_param fail_loc=0x8000031f
17808
17809         cancel_lru_locks osc &
17810         sleep 1
17811
17812 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
17813         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
17814         #IO takes another lock, but matches the PENDING one
17815         #and places it to the IO RPC
17816         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
17817                 error "failed to read a file with PENDING lock"
17818 }
17819 run_test 275 "Read on a canceled duplicate lock"
17820
17821 test_276() {
17822         remote_ost_nodsh && skip "remote OST with nodsh"
17823         local pid
17824
17825         do_facet ost1 "(while true; do \
17826                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
17827                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
17828         pid=$!
17829
17830         for LOOP in $(seq 20); do
17831                 stop ost1
17832                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
17833         done
17834         kill -9 $pid
17835         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
17836                 rm $TMP/sanity_276_pid"
17837 }
17838 run_test 276 "Race between mount and obd_statfs"
17839
17840 cleanup_test_300() {
17841         trap 0
17842         umask $SAVE_UMASK
17843 }
17844 test_striped_dir() {
17845         local mdt_index=$1
17846         local stripe_count
17847         local stripe_index
17848
17849         mkdir -p $DIR/$tdir
17850
17851         SAVE_UMASK=$(umask)
17852         trap cleanup_test_300 RETURN EXIT
17853
17854         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
17855                                                 $DIR/$tdir/striped_dir ||
17856                 error "set striped dir error"
17857
17858         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
17859         [ "$mode" = "755" ] || error "expect 755 got $mode"
17860
17861         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
17862                 error "getdirstripe failed"
17863         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
17864         if [ "$stripe_count" != "2" ]; then
17865                 error "1:stripe_count is $stripe_count, expect 2"
17866         fi
17867         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
17868         if [ "$stripe_count" != "2" ]; then
17869                 error "2:stripe_count is $stripe_count, expect 2"
17870         fi
17871
17872         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
17873         if [ "$stripe_index" != "$mdt_index" ]; then
17874                 error "stripe_index is $stripe_index, expect $mdt_index"
17875         fi
17876
17877         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
17878                 error "nlink error after create striped dir"
17879
17880         mkdir $DIR/$tdir/striped_dir/a
17881         mkdir $DIR/$tdir/striped_dir/b
17882
17883         stat $DIR/$tdir/striped_dir/a ||
17884                 error "create dir under striped dir failed"
17885         stat $DIR/$tdir/striped_dir/b ||
17886                 error "create dir under striped dir failed"
17887
17888         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
17889                 error "nlink error after mkdir"
17890
17891         rmdir $DIR/$tdir/striped_dir/a
17892         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
17893                 error "nlink error after rmdir"
17894
17895         rmdir $DIR/$tdir/striped_dir/b
17896         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
17897                 error "nlink error after rmdir"
17898
17899         chattr +i $DIR/$tdir/striped_dir
17900         createmany -o $DIR/$tdir/striped_dir/f 10 &&
17901                 error "immutable flags not working under striped dir!"
17902         chattr -i $DIR/$tdir/striped_dir
17903
17904         rmdir $DIR/$tdir/striped_dir ||
17905                 error "rmdir striped dir error"
17906
17907         cleanup_test_300
17908
17909         true
17910 }
17911
17912 test_300a() {
17913         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17914                 skip "skipped for lustre < 2.7.0"
17915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17916         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17917
17918         test_striped_dir 0 || error "failed on striped dir on MDT0"
17919         test_striped_dir 1 || error "failed on striped dir on MDT0"
17920 }
17921 run_test 300a "basic striped dir sanity test"
17922
17923 test_300b() {
17924         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17925                 skip "skipped for lustre < 2.7.0"
17926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17927         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17928
17929         local i
17930         local mtime1
17931         local mtime2
17932         local mtime3
17933
17934         test_mkdir $DIR/$tdir || error "mkdir fail"
17935         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
17936                 error "set striped dir error"
17937         for i in {0..9}; do
17938                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
17939                 sleep 1
17940                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
17941                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
17942                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
17943                 sleep 1
17944                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
17945                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
17946                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
17947         done
17948         true
17949 }
17950 run_test 300b "check ctime/mtime for striped dir"
17951
17952 test_300c() {
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 file_count
17959
17960         mkdir -p $DIR/$tdir
17961         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
17962                 error "set striped dir error"
17963
17964         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
17965                 error "chown striped dir failed"
17966
17967         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
17968                 error "create 5k files failed"
17969
17970         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
17971
17972         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
17973
17974         rm -rf $DIR/$tdir
17975 }
17976 run_test 300c "chown && check ls under striped directory"
17977
17978 test_300d() {
17979         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17980                 skip "skipped for lustre < 2.7.0"
17981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17982         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17983
17984         local stripe_count
17985         local file
17986
17987         mkdir -p $DIR/$tdir
17988         $LFS setstripe -c 2 $DIR/$tdir
17989
17990         #local striped directory
17991         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
17992                 error "set striped dir error"
17993         createmany -o $DIR/$tdir/striped_dir/f 10 ||
17994                 error "create 10 files failed"
17995
17996         #remote striped directory
17997         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
17998                 error "set striped dir error"
17999         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
18000                 error "create 10 files failed"
18001
18002         for file in $(find $DIR/$tdir); do
18003                 stripe_count=$($LFS getstripe -c $file)
18004                 [ $stripe_count -eq 2 ] ||
18005                         error "wrong stripe $stripe_count for $file"
18006         done
18007
18008         rm -rf $DIR/$tdir
18009 }
18010 run_test 300d "check default stripe under striped directory"
18011
18012 test_300e() {
18013         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18014                 skip "Need MDS version at least 2.7.55"
18015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18016         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18017
18018         local stripe_count
18019         local file
18020
18021         mkdir -p $DIR/$tdir
18022
18023         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18024                 error "set striped dir error"
18025
18026         touch $DIR/$tdir/striped_dir/a
18027         touch $DIR/$tdir/striped_dir/b
18028         touch $DIR/$tdir/striped_dir/c
18029
18030         mkdir $DIR/$tdir/striped_dir/dir_a
18031         mkdir $DIR/$tdir/striped_dir/dir_b
18032         mkdir $DIR/$tdir/striped_dir/dir_c
18033
18034         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
18035                 error "set striped adir under striped dir error"
18036
18037         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
18038                 error "set striped bdir under striped dir error"
18039
18040         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
18041                 error "set striped cdir under striped dir error"
18042
18043         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
18044                 error "rename dir under striped dir fails"
18045
18046         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
18047                 error "rename dir under different stripes fails"
18048
18049         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
18050                 error "rename file under striped dir should succeed"
18051
18052         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
18053                 error "rename dir under striped dir should succeed"
18054
18055         rm -rf $DIR/$tdir
18056 }
18057 run_test 300e "check rename under striped directory"
18058
18059 test_300f() {
18060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18061         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18062         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18063                 skip "Need MDS version at least 2.7.55"
18064
18065         local stripe_count
18066         local file
18067
18068         rm -rf $DIR/$tdir
18069         mkdir -p $DIR/$tdir
18070
18071         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18072                 error "set striped dir error"
18073
18074         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
18075                 error "set striped dir error"
18076
18077         touch $DIR/$tdir/striped_dir/a
18078         mkdir $DIR/$tdir/striped_dir/dir_a
18079         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
18080                 error "create striped dir under striped dir fails"
18081
18082         touch $DIR/$tdir/striped_dir1/b
18083         mkdir $DIR/$tdir/striped_dir1/dir_b
18084         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
18085                 error "create striped dir under striped dir fails"
18086
18087         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
18088                 error "rename dir under different striped dir should fail"
18089
18090         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
18091                 error "rename striped dir under diff striped dir should fail"
18092
18093         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
18094                 error "rename file under diff striped dirs fails"
18095
18096         rm -rf $DIR/$tdir
18097 }
18098 run_test 300f "check rename cross striped directory"
18099
18100 test_300_check_default_striped_dir()
18101 {
18102         local dirname=$1
18103         local default_count=$2
18104         local default_index=$3
18105         local stripe_count
18106         local stripe_index
18107         local dir_stripe_index
18108         local dir
18109
18110         echo "checking $dirname $default_count $default_index"
18111         $LFS setdirstripe -D -c $default_count -i $default_index \
18112                                 -t all_char $DIR/$tdir/$dirname ||
18113                 error "set default stripe on striped dir error"
18114         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
18115         [ $stripe_count -eq $default_count ] ||
18116                 error "expect $default_count get $stripe_count for $dirname"
18117
18118         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
18119         [ $stripe_index -eq $default_index ] ||
18120                 error "expect $default_index get $stripe_index for $dirname"
18121
18122         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
18123                                                 error "create dirs failed"
18124
18125         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
18126         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
18127         for dir in $(find $DIR/$tdir/$dirname/*); do
18128                 stripe_count=$($LFS getdirstripe -c $dir)
18129                 [ $stripe_count -eq $default_count ] ||
18130                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
18131                 error "stripe count $default_count != $stripe_count for $dir"
18132
18133                 stripe_index=$($LFS getdirstripe -i $dir)
18134                 [ $default_index -eq -1 ] ||
18135                         [ $stripe_index -eq $default_index ] ||
18136                         error "$stripe_index != $default_index for $dir"
18137
18138                 #check default stripe
18139                 stripe_count=$($LFS getdirstripe -D -c $dir)
18140                 [ $stripe_count -eq $default_count ] ||
18141                 error "default count $default_count != $stripe_count for $dir"
18142
18143                 stripe_index=$($LFS getdirstripe -D -i $dir)
18144                 [ $stripe_index -eq $default_index ] ||
18145                 error "default index $default_index != $stripe_index for $dir"
18146         done
18147         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
18148 }
18149
18150 test_300g() {
18151         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18152         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18153                 skip "Need MDS version at least 2.7.55"
18154
18155         local dir
18156         local stripe_count
18157         local stripe_index
18158
18159         mkdir $DIR/$tdir
18160         mkdir $DIR/$tdir/normal_dir
18161
18162         #Checking when client cache stripe index
18163         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
18164         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
18165                 error "create striped_dir failed"
18166
18167         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
18168                 error "create dir0 fails"
18169         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
18170         [ $stripe_index -eq 0 ] ||
18171                 error "dir0 expect index 0 got $stripe_index"
18172
18173         mkdir $DIR/$tdir/striped_dir/dir1 ||
18174                 error "create dir1 fails"
18175         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
18176         [ $stripe_index -eq 1 ] ||
18177                 error "dir1 expect index 1 got $stripe_index"
18178
18179         #check default stripe count/stripe index
18180         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
18181         test_300_check_default_striped_dir normal_dir 1 0
18182         test_300_check_default_striped_dir normal_dir 2 1
18183         test_300_check_default_striped_dir normal_dir 2 -1
18184
18185         #delete default stripe information
18186         echo "delete default stripeEA"
18187         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
18188                 error "set default stripe on striped dir error"
18189
18190         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
18191         for dir in $(find $DIR/$tdir/normal_dir/*); do
18192                 stripe_count=$($LFS getdirstripe -c $dir)
18193                 [ $stripe_count -eq 0 ] ||
18194                         error "expect 1 get $stripe_count for $dir"
18195                 stripe_index=$($LFS getdirstripe -i $dir)
18196                 [ $stripe_index -eq 0 ] ||
18197                         error "expect 0 get $stripe_index for $dir"
18198         done
18199 }
18200 run_test 300g "check default striped directory for normal directory"
18201
18202 test_300h() {
18203         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18204         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18205                 skip "Need MDS version at least 2.7.55"
18206
18207         local dir
18208         local stripe_count
18209
18210         mkdir $DIR/$tdir
18211         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18212                 error "set striped dir error"
18213
18214         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
18215         test_300_check_default_striped_dir striped_dir 1 0
18216         test_300_check_default_striped_dir striped_dir 2 1
18217         test_300_check_default_striped_dir striped_dir 2 -1
18218
18219         #delete default stripe information
18220         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
18221                 error "set default stripe on striped dir error"
18222
18223         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
18224         for dir in $(find $DIR/$tdir/striped_dir/*); do
18225                 stripe_count=$($LFS getdirstripe -c $dir)
18226                 [ $stripe_count -eq 0 ] ||
18227                         error "expect 1 get $stripe_count for $dir"
18228         done
18229 }
18230 run_test 300h "check default striped directory for striped directory"
18231
18232 test_300i() {
18233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18234         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18235         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18236                 skip "Need MDS version at least 2.7.55"
18237
18238         local stripe_count
18239         local file
18240
18241         mkdir $DIR/$tdir
18242
18243         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18244                 error "set striped dir error"
18245
18246         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18247                 error "create files under striped dir failed"
18248
18249         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
18250                 error "set striped hashdir error"
18251
18252         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
18253                 error "create dir0 under hash dir failed"
18254         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
18255                 error "create dir1 under hash dir failed"
18256
18257         # unfortunately, we need to umount to clear dir layout cache for now
18258         # once we fully implement dir layout, we can drop this
18259         umount_client $MOUNT || error "umount failed"
18260         mount_client $MOUNT || error "mount failed"
18261
18262         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
18263         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
18264         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
18265
18266         #set the stripe to be unknown hash type
18267         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
18268         $LCTL set_param fail_loc=0x1901
18269         for ((i = 0; i < 10; i++)); do
18270                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
18271                         error "stat f-$i failed"
18272                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
18273         done
18274
18275         touch $DIR/$tdir/striped_dir/f0 &&
18276                 error "create under striped dir with unknown hash should fail"
18277
18278         $LCTL set_param fail_loc=0
18279
18280         umount_client $MOUNT || error "umount failed"
18281         mount_client $MOUNT || error "mount failed"
18282
18283         return 0
18284 }
18285 run_test 300i "client handle unknown hash type striped directory"
18286
18287 test_300j() {
18288         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18290         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18291                 skip "Need MDS version at least 2.7.55"
18292
18293         local stripe_count
18294         local file
18295
18296         mkdir $DIR/$tdir
18297
18298         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
18299         $LCTL set_param fail_loc=0x1702
18300         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18301                 error "set striped dir error"
18302
18303         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18304                 error "create files under striped dir failed"
18305
18306         $LCTL set_param fail_loc=0
18307
18308         rm -rf $DIR/$tdir || error "unlink striped dir fails"
18309
18310         return 0
18311 }
18312 run_test 300j "test large update record"
18313
18314 test_300k() {
18315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18316         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18317         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18318                 skip "Need MDS version at least 2.7.55"
18319
18320         # this test needs a huge transaction
18321         local kb
18322         kb=$(do_facet $SINGLEMDS lctl get_param -n osd*.lustre-MDT0000.kbytestotal)
18323         [ $kb -lt $((1024*1024)) ] && skip "too small mds: $kb"
18324
18325         local stripe_count
18326         local file
18327
18328         mkdir $DIR/$tdir
18329
18330         #define OBD_FAIL_LARGE_STRIPE   0x1703
18331         $LCTL set_param fail_loc=0x1703
18332         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
18333                 error "set striped dir error"
18334         $LCTL set_param fail_loc=0
18335
18336         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18337                 error "getstripeddir fails"
18338         rm -rf $DIR/$tdir/striped_dir ||
18339                 error "unlink striped dir fails"
18340
18341         return 0
18342 }
18343 run_test 300k "test large striped directory"
18344
18345 test_300l() {
18346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18347         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18348         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18349                 skip "Need MDS version at least 2.7.55"
18350
18351         local stripe_index
18352
18353         test_mkdir -p $DIR/$tdir/striped_dir
18354         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
18355                         error "chown $RUNAS_ID failed"
18356         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
18357                 error "set default striped dir failed"
18358
18359         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
18360         $LCTL set_param fail_loc=0x80000158
18361         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
18362
18363         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
18364         [ $stripe_index -eq 1 ] ||
18365                 error "expect 1 get $stripe_index for $dir"
18366 }
18367 run_test 300l "non-root user to create dir under striped dir with stale layout"
18368
18369 test_300m() {
18370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18371         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
18372         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18373                 skip "Need MDS version at least 2.7.55"
18374
18375         mkdir -p $DIR/$tdir/striped_dir
18376         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
18377                 error "set default stripes dir error"
18378
18379         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
18380
18381         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
18382         [ $stripe_count -eq 0 ] ||
18383                         error "expect 0 get $stripe_count for a"
18384
18385         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
18386                 error "set default stripes dir error"
18387
18388         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
18389
18390         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
18391         [ $stripe_count -eq 0 ] ||
18392                         error "expect 0 get $stripe_count for b"
18393
18394         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
18395                 error "set default stripes dir error"
18396
18397         mkdir $DIR/$tdir/striped_dir/c &&
18398                 error "default stripe_index is invalid, mkdir c should fails"
18399
18400         rm -rf $DIR/$tdir || error "rmdir fails"
18401 }
18402 run_test 300m "setstriped directory on single MDT FS"
18403
18404 cleanup_300n() {
18405         local list=$(comma_list $(mdts_nodes))
18406
18407         trap 0
18408         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18409 }
18410
18411 test_300n() {
18412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18413         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18414         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18415                 skip "Need MDS version at least 2.7.55"
18416         remote_mds_nodsh && skip "remote MDS with nodsh"
18417
18418         local stripe_index
18419         local list=$(comma_list $(mdts_nodes))
18420
18421         trap cleanup_300n RETURN EXIT
18422         mkdir -p $DIR/$tdir
18423         chmod 777 $DIR/$tdir
18424         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
18425                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18426                 error "create striped dir succeeds with gid=0"
18427
18428         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18429         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
18430                 error "create striped dir fails with gid=-1"
18431
18432         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18433         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
18434                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18435                 error "set default striped dir succeeds with gid=0"
18436
18437
18438         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18439         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
18440                 error "set default striped dir fails with gid=-1"
18441
18442
18443         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18444         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
18445                                         error "create test_dir fails"
18446         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
18447                                         error "create test_dir1 fails"
18448         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
18449                                         error "create test_dir2 fails"
18450         cleanup_300n
18451 }
18452 run_test 300n "non-root user to create dir under striped dir with default EA"
18453
18454 test_300o() {
18455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18456         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18457         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18458                 skip "Need MDS version at least 2.7.55"
18459
18460         local numfree1
18461         local numfree2
18462
18463         mkdir -p $DIR/$tdir
18464
18465         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
18466         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
18467         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
18468                 skip "not enough free inodes $numfree1 $numfree2"
18469         fi
18470
18471         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
18472         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
18473         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
18474                 skip "not enough free space $numfree1 $numfree2"
18475         fi
18476
18477         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
18478                 error "setdirstripe fails"
18479
18480         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
18481                 error "create dirs fails"
18482
18483         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
18484         ls $DIR/$tdir/striped_dir > /dev/null ||
18485                 error "ls striped dir fails"
18486         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
18487                 error "unlink big striped dir fails"
18488 }
18489 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
18490
18491 test_300p() {
18492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18493         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18494         remote_mds_nodsh && skip "remote MDS with nodsh"
18495
18496         mkdir -p $DIR/$tdir
18497
18498         #define OBD_FAIL_OUT_ENOSPC     0x1704
18499         do_facet mds2 lctl set_param fail_loc=0x80001704
18500         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
18501                  && error "create striped directory should fail"
18502
18503         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
18504
18505         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
18506         true
18507 }
18508 run_test 300p "create striped directory without space"
18509
18510 test_300q() {
18511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18512         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18513
18514         local fd=$(free_fd)
18515         local cmd="exec $fd<$tdir"
18516         cd $DIR
18517         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
18518         eval $cmd
18519         cmd="exec $fd<&-"
18520         trap "eval $cmd" EXIT
18521         cd $tdir || error "cd $tdir fails"
18522         rmdir  ../$tdir || error "rmdir $tdir fails"
18523         mkdir local_dir && error "create dir succeeds"
18524         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
18525         eval $cmd
18526         return 0
18527 }
18528 run_test 300q "create remote directory under orphan directory"
18529
18530 test_300r() {
18531         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
18532                 skip "Need MDS version at least 2.7.55" && return
18533         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18534
18535         mkdir $DIR/$tdir
18536
18537         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
18538                 error "set striped dir error"
18539
18540         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18541                 error "getstripeddir fails"
18542
18543         local stripe_count
18544         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18545                       awk '/lmv_stripe_count:/ { print $2 }')
18546
18547         [ $MDSCOUNT -ne $stripe_count ] &&
18548                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
18549
18550         rm -rf $DIR/$tdir/striped_dir ||
18551                 error "unlink striped dir fails"
18552 }
18553 run_test 300r "test -1 striped directory"
18554
18555 prepare_remote_file() {
18556         mkdir $DIR/$tdir/src_dir ||
18557                 error "create remote source failed"
18558
18559         cp /etc/hosts $DIR/$tdir/src_dir/a ||
18560                  error "cp to remote source failed"
18561         touch $DIR/$tdir/src_dir/a
18562
18563         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
18564                 error "create remote target dir failed"
18565
18566         touch $DIR/$tdir/tgt_dir/b
18567
18568         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
18569                 error "rename dir cross MDT failed!"
18570
18571         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
18572                 error "src_child still exists after rename"
18573
18574         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
18575                 error "missing file(a) after rename"
18576
18577         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
18578                 error "diff after rename"
18579 }
18580
18581 test_310a() {
18582         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
18583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18584
18585         local remote_file=$DIR/$tdir/tgt_dir/b
18586
18587         mkdir -p $DIR/$tdir
18588
18589         prepare_remote_file || error "prepare remote file failed"
18590
18591         #open-unlink file
18592         $OPENUNLINK $remote_file $remote_file ||
18593                 error "openunlink $remote_file failed"
18594         $CHECKSTAT -a $remote_file || error "$remote_file exists"
18595 }
18596 run_test 310a "open unlink remote file"
18597
18598 test_310b() {
18599         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
18600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18601
18602         local remote_file=$DIR/$tdir/tgt_dir/b
18603
18604         mkdir -p $DIR/$tdir
18605
18606         prepare_remote_file || error "prepare remote file failed"
18607
18608         ln $remote_file $DIR/$tfile || error "link failed for remote file"
18609         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
18610         $CHECKSTAT -t file $remote_file || error "check file failed"
18611 }
18612 run_test 310b "unlink remote file with multiple links while open"
18613
18614 test_310c() {
18615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18616         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
18617
18618         local remote_file=$DIR/$tdir/tgt_dir/b
18619
18620         mkdir -p $DIR/$tdir
18621
18622         prepare_remote_file || error "prepare remote file failed"
18623
18624         ln $remote_file $DIR/$tfile || error "link failed for remote file"
18625         multiop_bg_pause $remote_file O_uc ||
18626                         error "mulitop failed for remote file"
18627         MULTIPID=$!
18628         $MULTIOP $DIR/$tfile Ouc
18629         kill -USR1 $MULTIPID
18630         wait $MULTIPID
18631 }
18632 run_test 310c "open-unlink remote file with multiple links"
18633
18634 #LU-4825
18635 test_311() {
18636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18637         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
18638         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
18639                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
18640         remote_mds_nodsh && skip "remote MDS with nodsh"
18641
18642         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
18643         local mdts=$(comma_list $(mdts_nodes))
18644
18645         mkdir -p $DIR/$tdir
18646         $LFS setstripe -i 0 -c 1 $DIR/$tdir
18647         createmany -o $DIR/$tdir/$tfile. 1000
18648
18649         # statfs data is not real time, let's just calculate it
18650         old_iused=$((old_iused + 1000))
18651
18652         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
18653                         osp.*OST0000*MDT0000.create_count")
18654         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
18655                                 osp.*OST0000*MDT0000.max_create_count")
18656         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
18657
18658         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
18659         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
18660         [ $index -ne 0 ] || error "$tfile stripe index is 0"
18661
18662         unlinkmany $DIR/$tdir/$tfile. 1000
18663
18664         do_nodes $mdts "$LCTL set_param -n \
18665                         osp.*OST0000*.max_create_count=$max_count"
18666         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
18667                 do_nodes $mdts "$LCTL set_param -n \
18668                                 osp.*OST0000*.create_count=$count"
18669         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
18670                         grep "=0" && error "create_count is zero"
18671
18672         local new_iused
18673         for i in $(seq 120); do
18674                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
18675                 # system may be too busy to destroy all objs in time, use
18676                 # a somewhat small value to not fail autotest
18677                 [ $((old_iused - new_iused)) -gt 400 ] && break
18678                 sleep 1
18679         done
18680
18681         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
18682         [ $((old_iused - new_iused)) -gt 400 ] ||
18683                 error "objs not destroyed after unlink"
18684 }
18685 run_test 311 "disable OSP precreate, and unlink should destroy objs"
18686
18687 zfs_oid_to_objid()
18688 {
18689         local ost=$1
18690         local objid=$2
18691
18692         local vdevdir=$(dirname $(facet_vdevice $ost))
18693         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
18694         local zfs_zapid=$(do_facet $ost $cmd |
18695                           grep -w "/O/0/d$((objid%32))" -C 5 |
18696                           awk '/Object/{getline; print $1}')
18697         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
18698                           awk "/$objid = /"'{printf $3}')
18699
18700         echo $zfs_objid
18701 }
18702
18703 zfs_object_blksz() {
18704         local ost=$1
18705         local objid=$2
18706
18707         local vdevdir=$(dirname $(facet_vdevice $ost))
18708         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
18709         local blksz=$(do_facet $ost $cmd $objid |
18710                       awk '/dblk/{getline; printf $4}')
18711
18712         case "${blksz: -1}" in
18713                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
18714                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
18715                 *) ;;
18716         esac
18717
18718         echo $blksz
18719 }
18720
18721 test_312() { # LU-4856
18722         remote_ost_nodsh && skip "remote OST with nodsh"
18723         [ "$ost1_FSTYPE" = "zfs" ] ||
18724                 skip_env "the test only applies to zfs"
18725
18726         local max_blksz=$(do_facet ost1 \
18727                           $ZFS get -p recordsize $(facet_device ost1) |
18728                           awk '!/VALUE/{print $3}')
18729
18730         # to make life a little bit easier
18731         $LFS mkdir -c 1 -i 0 $DIR/$tdir
18732         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18733
18734         local tf=$DIR/$tdir/$tfile
18735         touch $tf
18736         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18737
18738         # Get ZFS object id
18739         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18740         # block size change by sequential overwrite
18741         local bs
18742
18743         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
18744                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
18745
18746                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
18747                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
18748         done
18749         rm -f $tf
18750
18751         # block size change by sequential append write
18752         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
18753         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18754         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18755         local count
18756
18757         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
18758                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
18759                         oflag=sync conv=notrunc
18760
18761                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
18762                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
18763                         error "blksz error, actual $blksz, " \
18764                                 "expected: 2 * $count * $PAGE_SIZE"
18765         done
18766         rm -f $tf
18767
18768         # random write
18769         touch $tf
18770         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18771         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18772
18773         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
18774         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18775         [ $blksz -eq $PAGE_SIZE ] ||
18776                 error "blksz error: $blksz, expected: $PAGE_SIZE"
18777
18778         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
18779         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18780         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
18781
18782         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
18783         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18784         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
18785 }
18786 run_test 312 "make sure ZFS adjusts its block size by write pattern"
18787
18788 test_313() {
18789         remote_ost_nodsh && skip "remote OST with nodsh"
18790
18791         local file=$DIR/$tfile
18792
18793         rm -f $file
18794         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
18795
18796         # define OBD_FAIL_TGT_RCVD_EIO           0x720
18797         do_facet ost1 "$LCTL set_param fail_loc=0x720"
18798         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
18799                 error "write should failed"
18800         do_facet ost1 "$LCTL set_param fail_loc=0"
18801         rm -f $file
18802 }
18803 run_test 313 "io should fail after last_rcvd update fail"
18804
18805 test_314() {
18806         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
18807
18808         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
18809         do_facet ost1 "$LCTL set_param fail_loc=0x720"
18810         rm -f $DIR/$tfile
18811         wait_delete_completed
18812         do_facet ost1 "$LCTL set_param fail_loc=0"
18813 }
18814 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
18815
18816 test_315() { # LU-618
18817         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
18818
18819         local file=$DIR/$tfile
18820         rm -f $file
18821
18822         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
18823                 error "multiop file write failed"
18824         $MULTIOP $file oO_RDONLY:r4063232_c &
18825         PID=$!
18826
18827         sleep 2
18828
18829         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
18830         kill -USR1 $PID
18831
18832         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
18833         rm -f $file
18834 }
18835 run_test 315 "read should be accounted"
18836
18837 test_316() {
18838         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18839         large_xattr_enabled || skip_env "ea_inode feature disabled"
18840
18841         rm -rf $DIR/$tdir/d
18842         mkdir -p $DIR/$tdir/d
18843         chown nobody $DIR/$tdir/d
18844         touch $DIR/$tdir/d/file
18845
18846         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
18847 }
18848 run_test 316 "lfs mv"
18849
18850 test_317() {
18851         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
18852                 skip "Need MDS version at least 2.11.53"
18853         local trunc_sz
18854         local grant_blk_size
18855
18856         if [ "$(facet_fstype $facet)" == "zfs" ]; then
18857                 skip "LU-10370: no implementation for ZFS" && return
18858         fi
18859
18860         stack_trap "rm -f $DIR/$tfile" EXIT
18861         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
18862                         awk '/grant_block_size:/ { print $2; exit; }')
18863         #
18864         # Create File of size 5M. Truncate it to below size's and verify
18865         # blocks count.
18866         #
18867         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
18868                 error "Create file : $DIR/$tfile"
18869
18870         for trunc_sz in 2097152 4097 4000 509 0; do
18871                 $TRUNCATE $DIR/$tfile $trunc_sz ||
18872                         error "truncate $tfile to $trunc_sz failed"
18873                 local sz=$(stat --format=%s $DIR/$tfile)
18874                 local blk=$(stat --format=%b $DIR/$tfile)
18875                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
18876                                      grant_blk_size) * 8))
18877
18878                 if [[ $blk -ne $trunc_blk ]]; then
18879                         $(which stat) $DIR/$tfile
18880                         error "Expected Block $trunc_blk got $blk for $tfile"
18881                 fi
18882
18883                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
18884                         error "Expected Size $trunc_sz got $sz for $tfile"
18885         done
18886
18887         #
18888         # sparse file test
18889         # Create file with a hole and write actual two blocks. Block count
18890         # must be 16.
18891         #
18892         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
18893                 conv=fsync || error "Create file : $DIR/$tfile"
18894
18895         # Calculate the final truncate size.
18896         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
18897
18898         #
18899         # truncate to size $trunc_sz bytes. Strip the last block
18900         # The block count must drop to 8
18901         #
18902         $TRUNCATE $DIR/$tfile $trunc_sz ||
18903                 error "truncate $tfile to $trunc_sz failed"
18904
18905         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
18906         sz=$(stat --format=%s $DIR/$tfile)
18907         blk=$(stat --format=%b $DIR/$tfile)
18908
18909         if [[ $blk -ne $trunc_bsz ]]; then
18910                 $(which stat) $DIR/$tfile
18911                 error "Expected Block $trunc_bsz got $blk for $tfile"
18912         fi
18913
18914         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
18915                 error "Expected Size $trunc_sz got $sz for $tfile"
18916 }
18917 run_test 317 "Verify blocks get correctly update after truncate"
18918
18919 test_319() {
18920         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
18921
18922         local before=$(date +%s)
18923         local evict
18924         local mdir=$DIR/$tdir
18925         local file=$mdir/xxx
18926
18927         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
18928         touch $file
18929
18930 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
18931         $LCTL set_param fail_val=5 fail_loc=0x8000032c
18932         $LFS mv -m1 $file &
18933
18934         sleep 1
18935         dd if=$file of=/dev/null
18936         wait
18937         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
18938           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
18939
18940         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
18941 }
18942 run_test 319 "lost lease lock on migrate error"
18943
18944 test_fake_rw() {
18945         local read_write=$1
18946         if [ "$read_write" = "write" ]; then
18947                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
18948         elif [ "$read_write" = "read" ]; then
18949                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
18950         else
18951                 error "argument error"
18952         fi
18953
18954         # turn off debug for performance testing
18955         local saved_debug=$($LCTL get_param -n debug)
18956         $LCTL set_param debug=0
18957
18958         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18959
18960         # get ost1 size - lustre-OST0000
18961         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
18962         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
18963         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
18964
18965         if [ "$read_write" = "read" ]; then
18966                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
18967         fi
18968
18969         local start_time=$(date +%s.%N)
18970         $dd_cmd bs=1M count=$blocks oflag=sync ||
18971                 error "real dd $read_write error"
18972         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
18973
18974         if [ "$read_write" = "write" ]; then
18975                 rm -f $DIR/$tfile
18976         fi
18977
18978         # define OBD_FAIL_OST_FAKE_RW           0x238
18979         do_facet ost1 $LCTL set_param fail_loc=0x238
18980
18981         local start_time=$(date +%s.%N)
18982         $dd_cmd bs=1M count=$blocks oflag=sync ||
18983                 error "fake dd $read_write error"
18984         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
18985
18986         if [ "$read_write" = "write" ]; then
18987                 # verify file size
18988                 cancel_lru_locks osc
18989                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
18990                         error "$tfile size not $blocks MB"
18991         fi
18992         do_facet ost1 $LCTL set_param fail_loc=0
18993
18994         echo "fake $read_write $duration_fake vs. normal $read_write" \
18995                 "$duration in seconds"
18996         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
18997                 error_not_in_vm "fake write is slower"
18998
18999         $LCTL set_param -n debug="$saved_debug"
19000         rm -f $DIR/$tfile
19001 }
19002 test_399a() { # LU-7655 for OST fake write
19003         remote_ost_nodsh && skip "remote OST with nodsh"
19004
19005         test_fake_rw write
19006 }
19007 run_test 399a "fake write should not be slower than normal write"
19008
19009 test_399b() { # LU-8726 for OST fake read
19010         remote_ost_nodsh && skip "remote OST with nodsh"
19011         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
19012                 skip_env "ldiskfs only test"
19013         fi
19014
19015         test_fake_rw read
19016 }
19017 run_test 399b "fake read should not be slower than normal read"
19018
19019 test_400a() { # LU-1606, was conf-sanity test_74
19020         if ! which $CC > /dev/null 2>&1; then
19021                 skip_env "$CC is not installed"
19022         fi
19023
19024         local extra_flags=''
19025         local out=$TMP/$tfile
19026         local prefix=/usr/include/lustre
19027         local prog
19028
19029         if ! [[ -d $prefix ]]; then
19030                 # Assume we're running in tree and fixup the include path.
19031                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
19032                 extra_flags+=" -L$LUSTRE/utils/.lib"
19033         fi
19034
19035         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
19036                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
19037                         error "client api broken"
19038         done
19039         rm -f $out
19040 }
19041 run_test 400a "Lustre client api program can compile and link"
19042
19043 test_400b() { # LU-1606, LU-5011
19044         local header
19045         local out=$TMP/$tfile
19046         local prefix=/usr/include/linux/lustre
19047
19048         # We use a hard coded prefix so that this test will not fail
19049         # when run in tree. There are headers in lustre/include/lustre/
19050         # that are not packaged (like lustre_idl.h) and have more
19051         # complicated include dependencies (like config.h and lnet/types.h).
19052         # Since this test about correct packaging we just skip them when
19053         # they don't exist (see below) rather than try to fixup cppflags.
19054
19055         if ! which $CC > /dev/null 2>&1; then
19056                 skip_env "$CC is not installed"
19057         fi
19058
19059         for header in $prefix/*.h; do
19060                 if ! [[ -f "$header" ]]; then
19061                         continue
19062                 fi
19063
19064                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
19065                         continue # lustre_ioctl.h is internal header
19066                 fi
19067
19068                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
19069                         error "cannot compile '$header'"
19070         done
19071         rm -f $out
19072 }
19073 run_test 400b "packaged headers can be compiled"
19074
19075 test_401a() { #LU-7437
19076         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
19077         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
19078
19079         #count the number of parameters by "list_param -R"
19080         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
19081         #count the number of parameters by listing proc files
19082         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
19083         echo "proc_dirs='$proc_dirs'"
19084         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
19085         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
19086                       sort -u | wc -l)
19087
19088         [ $params -eq $procs ] ||
19089                 error "found $params parameters vs. $procs proc files"
19090
19091         # test the list_param -D option only returns directories
19092         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
19093         #count the number of parameters by listing proc directories
19094         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
19095                 sort -u | wc -l)
19096
19097         [ $params -eq $procs ] ||
19098                 error "found $params parameters vs. $procs proc files"
19099 }
19100 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
19101
19102 test_401b() {
19103         local save=$($LCTL get_param -n jobid_var)
19104         local tmp=testing
19105
19106         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
19107                 error "no error returned when setting bad parameters"
19108
19109         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
19110         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
19111
19112         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
19113         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
19114         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
19115 }
19116 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
19117
19118 test_401c() {
19119         local jobid_var_old=$($LCTL get_param -n jobid_var)
19120         local jobid_var_new
19121
19122         $LCTL set_param jobid_var= &&
19123                 error "no error returned for 'set_param a='"
19124
19125         jobid_var_new=$($LCTL get_param -n jobid_var)
19126         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19127                 error "jobid_var was changed by setting without value"
19128
19129         $LCTL set_param jobid_var &&
19130                 error "no error returned for 'set_param a'"
19131
19132         jobid_var_new=$($LCTL get_param -n jobid_var)
19133         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19134                 error "jobid_var was changed by setting without value"
19135 }
19136 run_test 401c "Verify 'lctl set_param' without value fails in either format."
19137
19138 test_401d() {
19139         local jobid_var_old=$($LCTL get_param -n jobid_var)
19140         local jobid_var_new
19141         local new_value="foo=bar"
19142
19143         $LCTL set_param jobid_var=$new_value ||
19144                 error "'set_param a=b' did not accept a value containing '='"
19145
19146         jobid_var_new=$($LCTL get_param -n jobid_var)
19147         [[ "$jobid_var_new" == "$new_value" ]] ||
19148                 error "'set_param a=b' failed on a value containing '='"
19149
19150         # Reset the jobid_var to test the other format
19151         $LCTL set_param jobid_var=$jobid_var_old
19152         jobid_var_new=$($LCTL get_param -n jobid_var)
19153         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19154                 error "failed to reset jobid_var"
19155
19156         $LCTL set_param jobid_var $new_value ||
19157                 error "'set_param a b' did not accept a value containing '='"
19158
19159         jobid_var_new=$($LCTL get_param -n jobid_var)
19160         [[ "$jobid_var_new" == "$new_value" ]] ||
19161                 error "'set_param a b' failed on a value containing '='"
19162
19163         $LCTL set_param jobid_var $jobid_var_old
19164         jobid_var_new=$($LCTL get_param -n jobid_var)
19165         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19166                 error "failed to reset jobid_var"
19167 }
19168 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
19169
19170 test_402() {
19171         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
19172         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
19173                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
19174         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
19175                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
19176                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
19177         remote_mds_nodsh && skip "remote MDS with nodsh"
19178
19179         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
19180 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
19181         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
19182         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
19183                 echo "Touch failed - OK"
19184 }
19185 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
19186
19187 test_403() {
19188         local file1=$DIR/$tfile.1
19189         local file2=$DIR/$tfile.2
19190         local tfile=$TMP/$tfile
19191
19192         rm -f $file1 $file2 $tfile
19193
19194         touch $file1
19195         ln $file1 $file2
19196
19197         # 30 sec OBD_TIMEOUT in ll_getattr()
19198         # right before populating st_nlink
19199         $LCTL set_param fail_loc=0x80001409
19200         stat -c %h $file1 > $tfile &
19201
19202         # create an alias, drop all locks and reclaim the dentry
19203         < $file2
19204         cancel_lru_locks mdc
19205         cancel_lru_locks osc
19206         sysctl -w vm.drop_caches=2
19207
19208         wait
19209
19210         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
19211
19212         rm -f $tfile $file1 $file2
19213 }
19214 run_test 403 "i_nlink should not drop to zero due to aliasing"
19215
19216 test_404() { # LU-6601
19217         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
19218                 skip "Need server version newer than 2.8.52"
19219         remote_mds_nodsh && skip "remote MDS with nodsh"
19220
19221         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
19222                 awk '/osp .*-osc-MDT/ { print $4}')
19223
19224         local osp
19225         for osp in $mosps; do
19226                 echo "Deactivate: " $osp
19227                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
19228                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19229                         awk -vp=$osp '$4 == p { print $2 }')
19230                 [ $stat = IN ] || {
19231                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19232                         error "deactivate error"
19233                 }
19234                 echo "Activate: " $osp
19235                 do_facet $SINGLEMDS $LCTL --device %$osp activate
19236                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19237                         awk -vp=$osp '$4 == p { print $2 }')
19238                 [ $stat = UP ] || {
19239                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19240                         error "activate error"
19241                 }
19242         done
19243 }
19244 run_test 404 "validate manual {de}activated works properly for OSPs"
19245
19246 test_405() {
19247         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19248         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
19249                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
19250                         skip "Layout swap lock is not supported"
19251
19252         check_swap_layouts_support
19253
19254         test_mkdir $DIR/$tdir
19255         swap_lock_test -d $DIR/$tdir ||
19256                 error "One layout swap locked test failed"
19257 }
19258 run_test 405 "Various layout swap lock tests"
19259
19260 test_406() {
19261         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19262         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19263         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19265         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
19266                 skip "Need MDS version at least 2.8.50"
19267
19268         local def_stripe_size=$($LFS getstripe -S $MOUNT)
19269         local test_pool=$TESTNAME
19270
19271         if ! combined_mgs_mds ; then
19272                 mount_mgs_client
19273         fi
19274         pool_add $test_pool || error "pool_add failed"
19275         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
19276                 error "pool_add_targets failed"
19277
19278         save_layout_restore_at_exit $MOUNT
19279
19280         # parent set default stripe count only, child will stripe from both
19281         # parent and fs default
19282         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
19283                 error "setstripe $MOUNT failed"
19284         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
19285         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
19286         for i in $(seq 10); do
19287                 local f=$DIR/$tdir/$tfile.$i
19288                 touch $f || error "touch failed"
19289                 local count=$($LFS getstripe -c $f)
19290                 [ $count -eq $OSTCOUNT ] ||
19291                         error "$f stripe count $count != $OSTCOUNT"
19292                 local offset=$($LFS getstripe -i $f)
19293                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
19294                 local size=$($LFS getstripe -S $f)
19295                 [ $size -eq $((def_stripe_size * 2)) ] ||
19296                         error "$f stripe size $size != $((def_stripe_size * 2))"
19297                 local pool=$($LFS getstripe -p $f)
19298                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
19299         done
19300
19301         # change fs default striping, delete parent default striping, now child
19302         # will stripe from new fs default striping only
19303         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
19304                 error "change $MOUNT default stripe failed"
19305         $LFS setstripe -c 0 $DIR/$tdir ||
19306                 error "delete $tdir default stripe failed"
19307         for i in $(seq 11 20); do
19308                 local f=$DIR/$tdir/$tfile.$i
19309                 touch $f || error "touch $f failed"
19310                 local count=$($LFS getstripe -c $f)
19311                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
19312                 local offset=$($LFS getstripe -i $f)
19313                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
19314                 local size=$($LFS getstripe -S $f)
19315                 [ $size -eq $def_stripe_size ] ||
19316                         error "$f stripe size $size != $def_stripe_size"
19317                 local pool=$($LFS getstripe -p $f)
19318                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
19319         done
19320
19321         unlinkmany $DIR/$tdir/$tfile. 1 20
19322
19323         local f=$DIR/$tdir/$tfile
19324         pool_remove_all_targets $test_pool $f
19325         pool_remove $test_pool $f
19326
19327         if ! combined_mgs_mds ; then
19328                 umount_mgs_client
19329         fi
19330 }
19331 run_test 406 "DNE support fs default striping"
19332
19333 test_407() {
19334         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19335         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19336                 skip "Need MDS version at least 2.8.55"
19337         remote_mds_nodsh && skip "remote MDS with nodsh"
19338
19339         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
19340                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
19341         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
19342                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
19343         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
19344
19345         #define OBD_FAIL_DT_TXN_STOP    0x2019
19346         for idx in $(seq $MDSCOUNT); do
19347                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
19348         done
19349         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
19350         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
19351                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
19352         true
19353 }
19354 run_test 407 "transaction fail should cause operation fail"
19355
19356 test_408() {
19357         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
19358
19359         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
19360         lctl set_param fail_loc=0x8000040a
19361         # let ll_prepare_partial_page() fail
19362         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
19363
19364         rm -f $DIR/$tfile
19365
19366         # create at least 100 unused inodes so that
19367         # shrink_icache_memory(0) should not return 0
19368         touch $DIR/$tfile-{0..100}
19369         rm -f $DIR/$tfile-{0..100}
19370         sync
19371
19372         echo 2 > /proc/sys/vm/drop_caches
19373 }
19374 run_test 408 "drop_caches should not hang due to page leaks"
19375
19376 test_409()
19377 {
19378         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19379
19380         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
19381         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
19382         touch $DIR/$tdir/guard || error "(2) Fail to create"
19383
19384         local PREFIX=$(str_repeat 'A' 128)
19385         echo "Create 1K hard links start at $(date)"
19386         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19387                 error "(3) Fail to hard link"
19388
19389         echo "Links count should be right although linkEA overflow"
19390         stat $DIR/$tdir/guard || error "(4) Fail to stat"
19391         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
19392         [ $linkcount -eq 1001 ] ||
19393                 error "(5) Unexpected hard links count: $linkcount"
19394
19395         echo "List all links start at $(date)"
19396         ls -l $DIR/$tdir/foo > /dev/null ||
19397                 error "(6) Fail to list $DIR/$tdir/foo"
19398
19399         echo "Unlink hard links start at $(date)"
19400         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19401                 error "(7) Fail to unlink"
19402         echo "Unlink hard links finished at $(date)"
19403 }
19404 run_test 409 "Large amount of cross-MDTs hard links on the same file"
19405
19406 test_410()
19407 {
19408         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
19409                 skip "Need client version at least 2.9.59"
19410
19411         # Create a file, and stat it from the kernel
19412         local testfile=$DIR/$tfile
19413         touch $testfile
19414
19415         local run_id=$RANDOM
19416         local my_ino=$(stat --format "%i" $testfile)
19417
19418         # Try to insert the module. This will always fail as the
19419         # module is designed to not be inserted.
19420         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
19421             &> /dev/null
19422
19423         # Anything but success is a test failure
19424         dmesg | grep -q \
19425             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
19426             error "no inode match"
19427 }
19428 run_test 410 "Test inode number returned from kernel thread"
19429
19430 cleanup_test411_cgroup() {
19431         trap 0
19432         rmdir "$1"
19433 }
19434
19435 test_411() {
19436         local cg_basedir=/sys/fs/cgroup/memory
19437         # LU-9966
19438         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
19439                 skip "no setup for cgroup"
19440
19441         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
19442                 error "test file creation failed"
19443         cancel_lru_locks osc
19444
19445         # Create a very small memory cgroup to force a slab allocation error
19446         local cgdir=$cg_basedir/osc_slab_alloc
19447         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
19448         trap "cleanup_test411_cgroup $cgdir" EXIT
19449         echo 2M > $cgdir/memory.kmem.limit_in_bytes
19450         echo 1M > $cgdir/memory.limit_in_bytes
19451
19452         # Should not LBUG, just be killed by oom-killer
19453         # dd will return 0 even allocation failure in some environment.
19454         # So don't check return value
19455         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
19456         cleanup_test411_cgroup $cgdir
19457
19458         return 0
19459 }
19460 run_test 411 "Slab allocation error with cgroup does not LBUG"
19461
19462 test_412() {
19463         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19464         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19465                 skip "Need server version at least 2.10.55"
19466         fi
19467
19468         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
19469                 error "mkdir failed"
19470         $LFS getdirstripe $DIR/$tdir
19471         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19472         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
19473                 error "expect $((MDSCOUT - 1)) get $stripe_index"
19474         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
19475         [ $stripe_count -eq 2 ] ||
19476                 error "expect 2 get $stripe_count"
19477 }
19478 run_test 412 "mkdir on specific MDTs"
19479
19480 test_413() {
19481         [ $MDSCOUNT -lt 2 ] &&
19482                 skip "We need at least 2 MDTs for this test"
19483
19484         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19485                 skip "Need server version at least 2.10.55"
19486         fi
19487
19488         mkdir $DIR/$tdir || error "mkdir failed"
19489
19490         # find MDT that is the most full
19491         local max=$($LFS df | grep MDT |
19492                 awk 'BEGIN { a=0 }
19493                         { sub("%", "", $5)
19494                           if (0+$5 >= a)
19495                           {
19496                                 a = $5
19497                                 b = $6
19498                           }
19499                         }
19500                      END { split(b, c, ":")
19501                            sub("]", "", c[2])
19502                            print c[2]
19503                          }')
19504
19505         for i in $(seq $((MDSCOUNT - 1))); do
19506                 $LFS mkdir -c $i $DIR/$tdir/d$i ||
19507                         error "mkdir d$i failed"
19508                 $LFS getdirstripe $DIR/$tdir/d$i
19509                 local stripe_index=$($LFS getdirstripe -i $DIR/$tdir/d$i)
19510                 [ $stripe_index -ne $max ] ||
19511                         error "don't expect $max"
19512         done
19513 }
19514 run_test 413 "mkdir on less full MDTs"
19515
19516 test_414() {
19517 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
19518         $LCTL set_param fail_loc=0x80000521
19519         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
19520         rm -f $DIR/$tfile
19521 }
19522 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
19523
19524 test_415() {
19525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19526         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
19527                 skip "Need server version at least 2.11.52"
19528
19529         # LU-11102
19530         local total
19531         local setattr_pid
19532         local start_time
19533         local end_time
19534         local duration
19535
19536         total=500
19537         # this test may be slow on ZFS
19538         [ "$mds1_FSTYPE" == "zfs" ] && total=100
19539
19540         # though this test is designed for striped directory, let's test normal
19541         # directory too since lock is always saved as CoS lock.
19542         test_mkdir $DIR/$tdir || error "mkdir $tdir"
19543         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
19544
19545         (
19546                 while true; do
19547                         touch $DIR/$tdir
19548                 done
19549         ) &
19550         setattr_pid=$!
19551
19552         start_time=$(date +%s)
19553         for i in $(seq $total); do
19554                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
19555                         > /dev/null
19556         done
19557         end_time=$(date +%s)
19558         duration=$((end_time - start_time))
19559
19560         kill -9 $setattr_pid
19561
19562         echo "rename $total files took $duration sec"
19563         [ $duration -lt 100 ] || error "rename took $duration sec"
19564 }
19565 run_test 415 "lock revoke is not missing"
19566
19567 test_416() {
19568         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
19569                 skip "Need server version at least 2.11.55"
19570
19571         # define OBD_FAIL_OSD_TXN_START    0x19a
19572         do_facet mds1 lctl set_param fail_loc=0x19a
19573
19574         lfs mkdir -c $MDSCOUNT $DIR/$tdir
19575
19576         true
19577 }
19578 run_test 416 "transaction start failure won't cause system hung"
19579
19580 cleanup_417() {
19581         trap 0
19582         do_nodes $(comma_list $(mdts_nodes)) \
19583                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
19584         do_nodes $(comma_list $(mdts_nodes)) \
19585                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
19586         do_nodes $(comma_list $(mdts_nodes)) \
19587                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
19588 }
19589
19590 test_417() {
19591         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19592         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
19593                 skip "Need MDS version at least 2.11.56"
19594
19595         trap cleanup_417 RETURN EXIT
19596
19597         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
19598         do_nodes $(comma_list $(mdts_nodes)) \
19599                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
19600         $LFS migrate -m 0 $DIR/$tdir.1 &&
19601                 error "migrate dir $tdir.1 should fail"
19602
19603         do_nodes $(comma_list $(mdts_nodes)) \
19604                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
19605         $LFS mkdir -i 1 $DIR/$tdir.2 &&
19606                 error "create remote dir $tdir.2 should fail"
19607
19608         do_nodes $(comma_list $(mdts_nodes)) \
19609                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
19610         $LFS mkdir -c 2 $DIR/$tdir.3 &&
19611                 error "create striped dir $tdir.3 should fail"
19612         true
19613 }
19614 run_test 417 "disable remote dir, striped dir and dir migration"
19615
19616 # Checks that the outputs of df [-i] and lfs df [-i] match
19617 #
19618 # usage: check_lfs_df <blocks | inodes> <mountpoint>
19619 check_lfs_df() {
19620         local dir=$2
19621         local inodes
19622         local df_out
19623         local lfs_df_out
19624         local count
19625         local passed=false
19626
19627         # blocks or inodes
19628         [ "$1" == "blocks" ] && inodes= || inodes="-i"
19629
19630         for count in {1..100}; do
19631                 cancel_lru_locks
19632                 sync; sleep 0.2
19633
19634                 # read the lines of interest
19635                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
19636                         error "df $inodes $dir | tail -n +2 failed"
19637                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
19638                         error "lfs df $inodes $dir | grep summary: failed"
19639
19640                 # skip first substrings of each output as they are different
19641                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
19642                 # compare the two outputs
19643                 passed=true
19644                 for i in {1..5}; do
19645                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
19646                 done
19647                 $passed && break
19648         done
19649
19650         if ! $passed; then
19651                 df -P $inodes $dir
19652                 echo
19653                 lfs df $inodes $dir
19654                 error "df and lfs df $1 output mismatch: "      \
19655                       "df ${inodes}: ${df_out[*]}, "            \
19656                       "lfs df ${inodes}: ${lfs_df_out[*]}"
19657         fi
19658 }
19659
19660 test_418() {
19661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19662
19663         local dir=$DIR/$tdir
19664         local numfiles=$((RANDOM % 4096 + 2))
19665         local numblocks=$((RANDOM % 256 + 1))
19666
19667         wait_delete_completed
19668         test_mkdir $dir
19669
19670         # check block output
19671         check_lfs_df blocks $dir
19672         # check inode output
19673         check_lfs_df inodes $dir
19674
19675         # create a single file and retest
19676         echo "Creating a single file and testing"
19677         createmany -o $dir/$tfile- 1 &>/dev/null ||
19678                 error "creating 1 file in $dir failed"
19679         check_lfs_df blocks $dir
19680         check_lfs_df inodes $dir
19681
19682         # create a random number of files
19683         echo "Creating $((numfiles - 1)) files and testing"
19684         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
19685                 error "creating $((numfiles - 1)) files in $dir failed"
19686
19687         # write a random number of blocks to the first test file
19688         echo "Writing $numblocks 4K blocks and testing"
19689         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
19690                 count=$numblocks &>/dev/null ||
19691                 error "dd to $dir/${tfile}-0 failed"
19692
19693         # retest
19694         check_lfs_df blocks $dir
19695         check_lfs_df inodes $dir
19696
19697         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
19698                 error "unlinking $numfiles files in $dir failed"
19699 }
19700 run_test 418 "df and lfs df outputs match"
19701
19702 test_419()
19703 {
19704         local dir=$DIR/$tdir
19705
19706         mkdir -p $dir
19707         touch $dir/file
19708
19709         cancel_lru_locks mdc
19710
19711         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
19712         $LCTL set_param fail_loc=0x1410
19713         cat $dir/file
19714         $LCTL set_param fail_loc=0
19715         rm -rf $dir
19716 }
19717 run_test 419 "Verify open file by name doesn't crash kernel"
19718
19719 prep_801() {
19720         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
19721         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
19722                 skip "Need server version at least 2.9.55"
19723
19724         start_full_debug_logging
19725 }
19726
19727 post_801() {
19728         stop_full_debug_logging
19729 }
19730
19731 barrier_stat() {
19732         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
19733                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
19734                            awk '/The barrier for/ { print $7 }')
19735                 echo $st
19736         else
19737                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
19738                 echo \'$st\'
19739         fi
19740 }
19741
19742 barrier_expired() {
19743         local expired
19744
19745         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
19746                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
19747                           awk '/will be expired/ { print $7 }')
19748         else
19749                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
19750         fi
19751
19752         echo $expired
19753 }
19754
19755 test_801a() {
19756         prep_801
19757
19758         echo "Start barrier_freeze at: $(date)"
19759         #define OBD_FAIL_BARRIER_DELAY          0x2202
19760         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
19761         do_facet mgs $LCTL barrier_freeze $FSNAME 10 &
19762
19763         sleep 2
19764         local b_status=$(barrier_stat)
19765         echo "Got barrier status at: $(date)"
19766         [ "$b_status" = "'freezing_p1'" ] ||
19767                 error "(1) unexpected barrier status $b_status"
19768
19769         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
19770         wait
19771         b_status=$(barrier_stat)
19772         [ "$b_status" = "'frozen'" ] ||
19773                 error "(2) unexpected barrier status $b_status"
19774
19775         local expired=$(barrier_expired)
19776         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
19777         sleep $((expired + 3))
19778
19779         b_status=$(barrier_stat)
19780         [ "$b_status" = "'expired'" ] ||
19781                 error "(3) unexpected barrier status $b_status"
19782
19783         do_facet mgs $LCTL barrier_freeze $FSNAME 10 ||
19784                 error "(4) fail to freeze barrier"
19785
19786         b_status=$(barrier_stat)
19787         [ "$b_status" = "'frozen'" ] ||
19788                 error "(5) unexpected barrier status $b_status"
19789
19790         echo "Start barrier_thaw at: $(date)"
19791         #define OBD_FAIL_BARRIER_DELAY          0x2202
19792         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
19793         do_facet mgs $LCTL barrier_thaw $FSNAME &
19794
19795         sleep 2
19796         b_status=$(barrier_stat)
19797         echo "Got barrier status at: $(date)"
19798         [ "$b_status" = "'thawing'" ] ||
19799                 error "(6) unexpected barrier status $b_status"
19800
19801         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
19802         wait
19803         b_status=$(barrier_stat)
19804         [ "$b_status" = "'thawed'" ] ||
19805                 error "(7) unexpected barrier status $b_status"
19806
19807         #define OBD_FAIL_BARRIER_FAILURE        0x2203
19808         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
19809         do_facet mgs $LCTL barrier_freeze $FSNAME
19810
19811         b_status=$(barrier_stat)
19812         [ "$b_status" = "'failed'" ] ||
19813                 error "(8) unexpected barrier status $b_status"
19814
19815         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19816         do_facet mgs $LCTL barrier_thaw $FSNAME
19817
19818         post_801
19819 }
19820 run_test 801a "write barrier user interfaces and stat machine"
19821
19822 test_801b() {
19823         prep_801
19824
19825         mkdir $DIR/$tdir || error "(1) fail to mkdir"
19826         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
19827         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
19828         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
19829         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
19830
19831         cancel_lru_locks mdc
19832
19833         # 180 seconds should be long enough
19834         do_facet mgs $LCTL barrier_freeze $FSNAME 180
19835
19836         local b_status=$(barrier_stat)
19837         [ "$b_status" = "'frozen'" ] ||
19838                 error "(6) unexpected barrier status $b_status"
19839
19840         mkdir $DIR/$tdir/d0/d10 &
19841         mkdir_pid=$!
19842
19843         touch $DIR/$tdir/d1/f13 &
19844         touch_pid=$!
19845
19846         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
19847         ln_pid=$!
19848
19849         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
19850         mv_pid=$!
19851
19852         rm -f $DIR/$tdir/d4/f12 &
19853         rm_pid=$!
19854
19855         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
19856
19857         # To guarantee taht the 'stat' is not blocked
19858         b_status=$(barrier_stat)
19859         [ "$b_status" = "'frozen'" ] ||
19860                 error "(8) unexpected barrier status $b_status"
19861
19862         # let above commands to run at background
19863         sleep 5
19864
19865         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
19866         ps -p $touch_pid || error "(10) touch should be blocked"
19867         ps -p $ln_pid || error "(11) link should be blocked"
19868         ps -p $mv_pid || error "(12) rename should be blocked"
19869         ps -p $rm_pid || error "(13) unlink should be blocked"
19870
19871         b_status=$(barrier_stat)
19872         [ "$b_status" = "'frozen'" ] ||
19873                 error "(14) unexpected barrier status $b_status"
19874
19875         do_facet mgs $LCTL barrier_thaw $FSNAME
19876         b_status=$(barrier_stat)
19877         [ "$b_status" = "'thawed'" ] ||
19878                 error "(15) unexpected barrier status $b_status"
19879
19880         wait $mkdir_pid || error "(16) mkdir should succeed"
19881         wait $touch_pid || error "(17) touch should succeed"
19882         wait $ln_pid || error "(18) link should succeed"
19883         wait $mv_pid || error "(19) rename should succeed"
19884         wait $rm_pid || error "(20) unlink should succeed"
19885
19886         post_801
19887 }
19888 run_test 801b "modification will be blocked by write barrier"
19889
19890 test_801c() {
19891         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19892
19893         prep_801
19894
19895         stop mds2 || error "(1) Fail to stop mds2"
19896
19897         do_facet mgs $LCTL barrier_freeze $FSNAME 30
19898
19899         local b_status=$(barrier_stat)
19900         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
19901                 do_facet mgs $LCTL barrier_thaw $FSNAME
19902                 error "(2) unexpected barrier status $b_status"
19903         }
19904
19905         do_facet mgs $LCTL barrier_rescan $FSNAME ||
19906                 error "(3) Fail to rescan barrier bitmap"
19907
19908         do_facet mgs $LCTL barrier_freeze $FSNAME 10
19909
19910         b_status=$(barrier_stat)
19911         [ "$b_status" = "'frozen'" ] ||
19912                 error "(4) unexpected barrier status $b_status"
19913
19914         do_facet mgs $LCTL barrier_thaw $FSNAME
19915         b_status=$(barrier_stat)
19916         [ "$b_status" = "'thawed'" ] ||
19917                 error "(5) unexpected barrier status $b_status"
19918
19919         local devname=$(mdsdevname 2)
19920
19921         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
19922
19923         do_facet mgs $LCTL barrier_rescan $FSNAME ||
19924                 error "(7) Fail to rescan barrier bitmap"
19925
19926         post_801
19927 }
19928 run_test 801c "rescan barrier bitmap"
19929
19930 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
19931 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
19932 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
19933
19934 cleanup_802a() {
19935         trap 0
19936
19937         stopall
19938         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
19939         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
19940         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
19941         setupall
19942 }
19943
19944 test_802a() {
19945
19946         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
19947         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
19948                 skip "Need server version at least 2.9.55"
19949
19950         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
19951
19952         mkdir $DIR/$tdir || error "(1) fail to mkdir"
19953
19954         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
19955                 error "(2) Fail to copy"
19956
19957         trap cleanup_802a EXIT
19958
19959         # sync by force before remount as readonly
19960         sync; sync_all_data; sleep 3; sync_all_data
19961
19962         stopall
19963
19964         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
19965         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
19966         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
19967
19968         echo "Mount the server as read only"
19969         setupall server_only || error "(3) Fail to start servers"
19970
19971         echo "Mount client without ro should fail"
19972         mount_client $MOUNT &&
19973                 error "(4) Mount client without 'ro' should fail"
19974
19975         echo "Mount client with ro should succeed"
19976         mount_client $MOUNT ro ||
19977                 error "(5) Mount client with 'ro' should succeed"
19978
19979         echo "Modify should be refused"
19980         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
19981
19982         echo "Read should be allowed"
19983         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
19984                 error "(7) Read should succeed under ro mode"
19985
19986         cleanup_802a
19987 }
19988 run_test 802a "simulate readonly device"
19989
19990 test_802b() {
19991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19992         remote_mds_nodsh && skip "remote MDS with nodsh"
19993
19994         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
19995                 skip "readonly option not available"
19996
19997         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
19998
19999         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
20000                 error "(2) Fail to copy"
20001
20002         # write back all cached data before setting MDT to readonly
20003         cancel_lru_locks
20004         sync_all_data
20005
20006         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
20007         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
20008
20009         echo "Modify should be refused"
20010         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
20011
20012         echo "Read should be allowed"
20013         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
20014                 error "(7) Read should succeed under ro mode"
20015
20016         # disable readonly
20017         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
20018 }
20019 run_test 802b "be able to set MDTs to readonly"
20020
20021 test_803() {
20022         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20023         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
20024                 skip "MDS needs to be newer than 2.10.54"
20025
20026         mkdir -p $DIR/$tdir
20027         # Create some objects on all MDTs to trigger related logs objects
20028         for idx in $(seq $MDSCOUNT); do
20029                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
20030                         $DIR/$tdir/dir${idx} ||
20031                         error "Fail to create $DIR/$tdir/dir${idx}"
20032         done
20033
20034         sync; sleep 3
20035         wait_delete_completed # ensure old test cleanups are finished
20036         echo "before create:"
20037         $LFS df -i $MOUNT
20038         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20039
20040         for i in {1..10}; do
20041                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
20042                         error "Fail to create $DIR/$tdir/foo$i"
20043         done
20044
20045         sync; sleep 3
20046         echo "after create:"
20047         $LFS df -i $MOUNT
20048         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20049
20050         # allow for an llog to be cleaned up during the test
20051         [ $after_used -ge $((before_used + 10 - 1)) ] ||
20052                 error "before ($before_used) + 10 > after ($after_used)"
20053
20054         for i in {1..10}; do
20055                 rm -rf $DIR/$tdir/foo$i ||
20056                         error "Fail to remove $DIR/$tdir/foo$i"
20057         done
20058
20059         sleep 3 # avoid MDT return cached statfs
20060         wait_delete_completed
20061         echo "after unlink:"
20062         $LFS df -i $MOUNT
20063         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20064
20065         # allow for an llog to be created during the test
20066         [ $after_used -le $((before_used + 1)) ] ||
20067                 error "after ($after_used) > before ($before_used) + 1"
20068 }
20069 run_test 803 "verify agent object for remote object"
20070
20071 test_804() {
20072         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20073         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
20074                 skip "MDS needs to be newer than 2.10.54"
20075         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20076
20077         mkdir -p $DIR/$tdir
20078         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
20079                 error "Fail to create $DIR/$tdir/dir0"
20080
20081         local fid=$($LFS path2fid $DIR/$tdir/dir0)
20082         local dev=$(mdsdevname 2)
20083
20084         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20085                 grep ${fid} || error "NOT found agent entry for dir0"
20086
20087         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
20088                 error "Fail to create $DIR/$tdir/dir1"
20089
20090         touch $DIR/$tdir/dir1/foo0 ||
20091                 error "Fail to create $DIR/$tdir/dir1/foo0"
20092         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
20093         local rc=0
20094
20095         for idx in $(seq $MDSCOUNT); do
20096                 dev=$(mdsdevname $idx)
20097                 do_facet mds${idx} \
20098                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20099                         grep ${fid} && rc=$idx
20100         done
20101
20102         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
20103                 error "Fail to rename foo0 to foo1"
20104         if [ $rc -eq 0 ]; then
20105                 for idx in $(seq $MDSCOUNT); do
20106                         dev=$(mdsdevname $idx)
20107                         do_facet mds${idx} \
20108                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20109                         grep ${fid} && rc=$idx
20110                 done
20111         fi
20112
20113         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
20114                 error "Fail to rename foo1 to foo2"
20115         if [ $rc -eq 0 ]; then
20116                 for idx in $(seq $MDSCOUNT); do
20117                         dev=$(mdsdevname $idx)
20118                         do_facet mds${idx} \
20119                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20120                         grep ${fid} && rc=$idx
20121                 done
20122         fi
20123
20124         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
20125
20126         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
20127                 error "Fail to link to $DIR/$tdir/dir1/foo2"
20128         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
20129                 error "Fail to rename foo2 to foo0"
20130         unlink $DIR/$tdir/dir1/foo0 ||
20131                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
20132         rm -rf $DIR/$tdir/dir0 ||
20133                 error "Fail to rm $DIR/$tdir/dir0"
20134
20135         for idx in $(seq $MDSCOUNT); do
20136                 dev=$(mdsdevname $idx)
20137                 rc=0
20138
20139                 stop mds${idx}
20140                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
20141                         rc=$?
20142                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
20143                         error "mount mds$idx failed"
20144                 df $MOUNT > /dev/null 2>&1
20145
20146                 # e2fsck should not return error
20147                 [ $rc -eq 0 ] ||
20148                         error "e2fsck detected error on MDT${idx}: rc=$rc"
20149         done
20150 }
20151 run_test 804 "verify agent entry for remote entry"
20152
20153 cleanup_805() {
20154         do_facet $SINGLEMDS zfs set quota=$old $fsset
20155         unlinkmany $DIR/$tdir/f- 1000000
20156         trap 0
20157 }
20158
20159 test_805() {
20160         local zfs_version=$(do_node $SINGLEMDS cat /sys/module/zfs/version)
20161         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
20162         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
20163                 skip "netfree not implemented before 0.7"
20164         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
20165                 skip "Need MDS version at least 2.10.57"
20166
20167         local fsset
20168         local freekb
20169         local usedkb
20170         local old
20171         local quota
20172         local pref="osd-zfs.lustre-MDT0000."
20173
20174         # limit available space on MDS dataset to meet nospace issue
20175         # quickly. then ZFS 0.7.2 can use reserved space if asked
20176         # properly (using netfree flag in osd_declare_destroy()
20177         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
20178         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
20179                 gawk '{print $3}')
20180         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
20181         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
20182         let "usedkb=usedkb-freekb"
20183         let "freekb=freekb/2"
20184         if let "freekb > 5000"; then
20185                 let "freekb=5000"
20186         fi
20187         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
20188         trap cleanup_805 EXIT
20189         mkdir $DIR/$tdir
20190         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
20191         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
20192         rm -rf $DIR/$tdir || error "not able to remove"
20193         do_facet $SINGLEMDS zfs set quota=$old $fsset
20194         trap 0
20195 }
20196 run_test 805 "ZFS can remove from full fs"
20197
20198 # Size-on-MDS test
20199 check_lsom_data()
20200 {
20201         local file=$1
20202         local size=$($LFS getsom -s $file)
20203         local expect=$(stat -c %s $file)
20204
20205         [[ $size == $expect ]] ||
20206                 error "$file expected size: $expect, got: $size"
20207
20208         local blocks=$($LFS getsom -b $file)
20209         expect=$(stat -c %b $file)
20210         [[ $blocks == $expect ]] ||
20211                 error "$file expected blocks: $expect, got: $blocks"
20212 }
20213
20214 check_lsom_size()
20215 {
20216         local size=$($LFS getsom -s $1)
20217         local expect=$2
20218
20219         [[ $size == $expect ]] ||
20220                 error "$file expected size: $expect, got: $size"
20221 }
20222
20223 test_806() {
20224         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20225                 skip "Need MDS version at least 2.11.52"
20226
20227         local bs=1048576
20228
20229         touch $DIR/$tfile || error "touch $tfile failed"
20230
20231         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20232         save_lustre_params client "llite.*.xattr_cache" > $save
20233         lctl set_param llite.*.xattr_cache=0
20234         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20235
20236         # single-threaded write
20237         echo "Test SOM for single-threaded write"
20238         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
20239                 error "write $tfile failed"
20240         check_lsom_size $DIR/$tfile $bs
20241
20242         local num=32
20243         local size=$(($num * $bs))
20244         local offset=0
20245         local i
20246
20247         echo "Test SOM for single client multi-threaded($num) write"
20248         $TRUNCATE $DIR/$tfile 0
20249         for ((i = 0; i < $num; i++)); do
20250                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20251                 local pids[$i]=$!
20252                 offset=$((offset + $bs))
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         $TRUNCATE $DIR/$tfile 0
20260         for ((i = 0; i < $num; i++)); do
20261                 offset=$((offset - $bs))
20262                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20263                 local pids[$i]=$!
20264         done
20265         for (( i=0; i < $num; i++ )); do
20266                 wait ${pids[$i]}
20267         done
20268         check_lsom_size $DIR/$tfile $size
20269
20270         # multi-client wirtes
20271         num=$(get_node_count ${CLIENTS//,/ })
20272         size=$(($num * $bs))
20273         offset=0
20274         i=0
20275
20276         echo "Test SOM for multi-client ($num) writes"
20277         $TRUNCATE $DIR/$tfile 0
20278         for client in ${CLIENTS//,/ }; do
20279                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20280                 local pids[$i]=$!
20281                 i=$((i + 1))
20282                 offset=$((offset + $bs))
20283         done
20284         for (( i=0; i < $num; i++ )); do
20285                 wait ${pids[$i]}
20286         done
20287         check_lsom_size $DIR/$tfile $offset
20288
20289         i=0
20290         $TRUNCATE $DIR/$tfile 0
20291         for client in ${CLIENTS//,/ }; do
20292                 offset=$((offset - $bs))
20293                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20294                 local pids[$i]=$!
20295                 i=$((i + 1))
20296         done
20297         for (( i=0; i < $num; i++ )); do
20298                 wait ${pids[$i]}
20299         done
20300         check_lsom_size $DIR/$tfile $size
20301
20302         # verify truncate
20303         echo "Test SOM for truncate"
20304         $TRUNCATE $DIR/$tfile 1048576
20305         check_lsom_size $DIR/$tfile 1048576
20306         $TRUNCATE $DIR/$tfile 1234
20307         check_lsom_size $DIR/$tfile 1234
20308
20309         # verify SOM blocks count
20310         echo "Verify SOM block count"
20311         $TRUNCATE $DIR/$tfile 0
20312         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
20313                 error "failed to write file $tfile"
20314         check_lsom_data $DIR/$tfile
20315 }
20316 run_test 806 "Verify Lazy Size on MDS"
20317
20318 test_807() {
20319         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
20320         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20321                 skip "Need MDS version at least 2.11.52"
20322
20323         # Registration step
20324         changelog_register || error "changelog_register failed"
20325         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
20326         changelog_users $SINGLEMDS | grep -q $cl_user ||
20327                 error "User $cl_user not found in changelog_users"
20328
20329         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20330         save_lustre_params client "llite.*.xattr_cache" > $save
20331         lctl set_param llite.*.xattr_cache=0
20332         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20333
20334         rm -rf $DIR/$tdir || error "rm $tdir failed"
20335         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
20336         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
20337         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
20338         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
20339                 error "truncate $tdir/trunc failed"
20340
20341         local bs=1048576
20342         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
20343                 error "write $tfile failed"
20344
20345         # multi-client wirtes
20346         local num=$(get_node_count ${CLIENTS//,/ })
20347         local offset=0
20348         local i=0
20349
20350         echo "Test SOM for multi-client ($num) writes"
20351         touch $DIR/$tfile || error "touch $tfile failed"
20352         $TRUNCATE $DIR/$tfile 0
20353         for client in ${CLIENTS//,/ }; do
20354                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20355                 local pids[$i]=$!
20356                 i=$((i + 1))
20357                 offset=$((offset + $bs))
20358         done
20359         for (( i=0; i < $num; i++ )); do
20360                 wait ${pids[$i]}
20361         done
20362
20363         sleep 5
20364         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
20365         check_lsom_data $DIR/$tdir/trunc
20366         check_lsom_data $DIR/$tdir/single_dd
20367         check_lsom_data $DIR/$tfile
20368
20369         rm -rf $DIR/$tdir
20370         # Deregistration step
20371         changelog_deregister || error "changelog_deregister failed"
20372 }
20373 run_test 807 "verify LSOM syncing tool"
20374
20375 check_som_nologged()
20376 {
20377         local lines=$($LFS changelog $FSNAME-MDT0000 |
20378                 grep 'x=trusted.som' | wc -l)
20379         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
20380 }
20381
20382 test_808() {
20383         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
20384                 skip "Need MDS version at least 2.11.55"
20385
20386         # Registration step
20387         changelog_register || error "changelog_register failed"
20388
20389         touch $DIR/$tfile || error "touch $tfile failed"
20390         check_som_nologged
20391
20392         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
20393                 error "write $tfile failed"
20394         check_som_nologged
20395
20396         $TRUNCATE $DIR/$tfile 1234
20397         check_som_nologged
20398
20399         $TRUNCATE $DIR/$tfile 1048576
20400         check_som_nologged
20401
20402         # Deregistration step
20403         changelog_deregister || error "changelog_deregister failed"
20404 }
20405 run_test 808 "Check trusted.som xattr not logged in Changelogs"
20406
20407 check_som_nodata()
20408 {
20409         $LFS getsom $1
20410         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
20411 }
20412
20413 test_809() {
20414         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20415                 skip "Need MDS version at least 2.11.56"
20416
20417         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
20418                 error "failed to create DoM-only file $DIR/$tfile"
20419         touch $DIR/$tfile || error "touch $tfile failed"
20420         check_som_nodata $DIR/$tfile
20421
20422         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
20423                 error "write $tfile failed"
20424         check_som_nodata $DIR/$tfile
20425
20426         $TRUNCATE $DIR/$tfile 1234
20427         check_som_nodata $DIR/$tfile
20428
20429         $TRUNCATE $DIR/$tfile 4097
20430         check_som_nodata $DIR/$file
20431 }
20432 run_test 809 "Verify no SOM xattr store for DoM-only files"
20433
20434 test_810() {
20435         local ORIG
20436         local CSUM
20437
20438         # t10 seem to dislike partial pages
20439         lctl set_param osc.*.checksum_type=adler
20440         lctl set_param fail_loc=0x411
20441         dd if=/dev/urandom of=$DIR/$tfile bs=10240 count=2
20442         ORIG=$(md5sum $DIR/$tfile)
20443         lctl set_param ldlm.namespaces.*osc*.lru_size=clear
20444         CSUM=$(md5sum $DIR/$tfile)
20445         set_checksum_type adler
20446         if [ "$ORIG" != "$CSUM" ]; then
20447                 error "$ORIG != $CSUM"
20448         fi
20449 }
20450 run_test 810 "partial page writes on ZFS (LU-11663)"
20451
20452 test_811() {
20453         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
20454                 skip "Need MDS version at least 2.11.56"
20455
20456         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
20457         do_facet mds1 $LCTL set_param fail_loc=0x165
20458         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
20459
20460         stop mds1
20461         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20462
20463         sleep 5
20464         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
20465                 error "MDD orphan cleanup thread not quit"
20466 }
20467 run_test 811 "orphan name stub can be cleaned up in startup"
20468
20469 test_812() {
20470         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
20471                 skip "OST < 2.12.51 doesn't support this fail_loc"
20472
20473         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20474         # ensure ost1 is connected
20475         stat $DIR/$tfile >/dev/null || error "can't stat"
20476         wait_osc_import_state client ost1 FULL
20477         # no locks, no reqs to let the connection idle
20478         cancel_lru_locks osc
20479
20480         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
20481 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
20482         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
20483         wait_osc_import_state client ost1 CONNECTING
20484         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
20485
20486         stat $DIR/$tfile >/dev/null || error "can't stat file"
20487 }
20488 run_test 812 "do not drop reqs generated when imp is going to idle (LU-11951)"
20489
20490 test_813() {
20491         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
20492         [ -z "$file_heat_sav" ] && skip "no file heat support"
20493
20494         local readsample
20495         local writesample
20496         local readbyte
20497         local writebyte
20498         local readsample1
20499         local writesample1
20500         local readbyte1
20501         local writebyte1
20502
20503         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
20504         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
20505
20506         $LCTL set_param -n llite.*.file_heat=1
20507         echo "Turn on file heat"
20508         echo "Period second: $period_second, Decay percentage: $decay_pct"
20509
20510         echo "QQQQ" > $DIR/$tfile
20511         echo "QQQQ" > $DIR/$tfile
20512         echo "QQQQ" > $DIR/$tfile
20513         cat $DIR/$tfile > /dev/null
20514         cat $DIR/$tfile > /dev/null
20515         cat $DIR/$tfile > /dev/null
20516         cat $DIR/$tfile > /dev/null
20517
20518         local out=$($LFS heat_get $DIR/$tfile)
20519
20520         $LFS heat_get $DIR/$tfile
20521         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20522         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20523         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20524         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20525
20526         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
20527         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
20528         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
20529         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
20530
20531         sleep $((period_second + 3))
20532         echo "Sleep $((period_second + 3)) seconds..."
20533         # The recursion formula to calculate the heat of the file f is as
20534         # follow:
20535         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
20536         # Where Hi is the heat value in the period between time points i*I and
20537         # (i+1)*I; Ci is the access count in the period; the symbol P refers
20538         # to the weight of Ci.
20539         out=$($LFS heat_get $DIR/$tfile)
20540         $LFS heat_get $DIR/$tfile
20541         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20542         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20543         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20544         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20545
20546         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
20547                 error "read sample ($readsample) is wrong"
20548         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
20549                 error "write sample ($writesample) is wrong"
20550         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
20551                 error "read bytes ($readbyte) is wrong"
20552         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
20553                 error "write bytes ($writebyte) is wrong"
20554
20555         echo "QQQQ" > $DIR/$tfile
20556         echo "QQQQ" > $DIR/$tfile
20557         echo "QQQQ" > $DIR/$tfile
20558         cat $DIR/$tfile > /dev/null
20559         cat $DIR/$tfile > /dev/null
20560         cat $DIR/$tfile > /dev/null
20561         cat $DIR/$tfile > /dev/null
20562
20563         sleep $((period_second + 3))
20564         echo "Sleep $((period_second + 3)) seconds..."
20565
20566         out=$($LFS heat_get $DIR/$tfile)
20567         $LFS heat_get $DIR/$tfile
20568         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20569         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20570         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20571         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20572
20573         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
20574                 4 * $decay_pct) / 100") -eq 1 ] ||
20575                 error "read sample ($readsample1) is wrong"
20576         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
20577                 3 * $decay_pct) / 100") -eq 1 ] ||
20578                 error "write sample ($writesample1) is wrong"
20579         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
20580                 20 * $decay_pct) / 100") -eq 1 ] ||
20581                 error "read bytes ($readbyte1) is wrong"
20582         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
20583                 15 * $decay_pct) / 100") -eq 1 ] ||
20584                 error "write bytes ($writebyte1) is wrong"
20585
20586         echo "Turn off file heat for the file $DIR/$tfile"
20587         $LFS heat_set -o $DIR/$tfile
20588
20589         echo "QQQQ" > $DIR/$tfile
20590         echo "QQQQ" > $DIR/$tfile
20591         echo "QQQQ" > $DIR/$tfile
20592         cat $DIR/$tfile > /dev/null
20593         cat $DIR/$tfile > /dev/null
20594         cat $DIR/$tfile > /dev/null
20595         cat $DIR/$tfile > /dev/null
20596
20597         out=$($LFS heat_get $DIR/$tfile)
20598         $LFS heat_get $DIR/$tfile
20599         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20600         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20601         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20602         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20603
20604         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
20605         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
20606         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
20607         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
20608
20609         echo "Trun on file heat for the file $DIR/$tfile"
20610         $LFS heat_set -O $DIR/$tfile
20611
20612         echo "QQQQ" > $DIR/$tfile
20613         echo "QQQQ" > $DIR/$tfile
20614         echo "QQQQ" > $DIR/$tfile
20615         cat $DIR/$tfile > /dev/null
20616         cat $DIR/$tfile > /dev/null
20617         cat $DIR/$tfile > /dev/null
20618         cat $DIR/$tfile > /dev/null
20619
20620         out=$($LFS heat_get $DIR/$tfile)
20621         $LFS heat_get $DIR/$tfile
20622         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20623         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20624         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20625         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20626
20627         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
20628         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
20629         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
20630         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
20631
20632         $LFS heat_set -c $DIR/$tfile
20633         $LCTL set_param -n llite.*.file_heat=0
20634         echo "Turn off file heat support for the Lustre filesystem"
20635
20636         echo "QQQQ" > $DIR/$tfile
20637         echo "QQQQ" > $DIR/$tfile
20638         echo "QQQQ" > $DIR/$tfile
20639         cat $DIR/$tfile > /dev/null
20640         cat $DIR/$tfile > /dev/null
20641         cat $DIR/$tfile > /dev/null
20642         cat $DIR/$tfile > /dev/null
20643
20644         out=$($LFS heat_get $DIR/$tfile)
20645         $LFS heat_get $DIR/$tfile
20646         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20647         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20648         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20649         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20650
20651         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
20652         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
20653         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
20654         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
20655
20656         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
20657         rm -f $DIR/$tfile
20658 }
20659 run_test 813 "File heat verfication"
20660
20661 #
20662 # tests that do cleanup/setup should be run at the end
20663 #
20664
20665 test_900() {
20666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20667         local ls
20668
20669         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
20670         $LCTL set_param fail_loc=0x903
20671
20672         cancel_lru_locks MGC
20673
20674         FAIL_ON_ERROR=true cleanup
20675         FAIL_ON_ERROR=true setup
20676 }
20677 run_test 900 "umount should not race with any mgc requeue thread"
20678
20679 complete $SECONDS
20680 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
20681 check_and_cleanup_lustre
20682 if [ "$I_MOUNTED" != "yes" ]; then
20683         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
20684 fi
20685 exit_status