Whamcloud - gitweb
LU-9846 lod: Add overstriping support
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 # -*- tab-width: 8; indent-tabs-mode: t; -*-
3 #
4 # Run select tests by setting ONLY, or as arguments to the script.
5 # Skip specific tests by setting EXCEPT.
6 #
7 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
8 set -e
9
10 ONLY=${ONLY:-"$*"}
11 # bug number for skipped test: LU-9693 LU-6493 LU-9693
12 ALWAYS_EXCEPT="$SANITY_EXCEPT  42a     42b     42c"
13 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
14
15 # skipped tests: LU-8411 LU-9096 LU-9054 ..
16 ALWAYS_EXCEPT="  407     253     312     $ALWAYS_EXCEPT"
17
18 if $SHARED_KEY; then
19 # bug number for skipped tests: LU-9795 (all below)
20         ALWAYS_EXCEPT="$ALWAYS_EXCEPT   17n     60a     133g    300f"
21 fi
22
23 # Check Grants after these tests
24 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
25
26 # skip the grant tests for ARM until they are fixed
27 if [[ $(uname -m) = aarch64 ]]; then
28         # bug number:    LU-11596 (all below)
29         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
30         # bug number:    LU-11671 LU-11594 LU-11667 LU-11729
31         ALWAYS_EXCEPT+=" 45       103a      317      810"
32 fi
33
34 SRCDIR=$(cd $(dirname $0); echo $PWD)
35 export PATH=$PATH:/sbin
36
37 TMP=${TMP:-/tmp}
38 OSC=${OSC:-"osc"}
39
40 CC=${CC:-cc}
41 CHECKSTAT=${CHECKSTAT:-"checkstat -v"}
42 CREATETEST=${CREATETEST:-createtest}
43 LFS=${LFS:-lfs}
44 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
45 LCTL=${LCTL:-lctl}
46 OPENFILE=${OPENFILE:-openfile}
47 OPENUNLINK=${OPENUNLINK:-openunlink}
48 export MULTIOP=${MULTIOP:-multiop}
49 READS=${READS:-"reads"}
50 MUNLINK=${MUNLINK:-munlink}
51 SOCKETSERVER=${SOCKETSERVER:-socketserver}
52 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
53 MEMHOG=${MEMHOG:-memhog}
54 DIRECTIO=${DIRECTIO:-directio}
55 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
56 DEF_STRIPE_COUNT=-1
57 CHECK_GRANT=${CHECK_GRANT:-"yes"}
58 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
59 export PARALLEL=${PARALLEL:-"no"}
60
61 export NAME=${NAME:-local}
62
63 SAVE_PWD=$PWD
64
65 CLEANUP=${CLEANUP:-:}
66 SETUP=${SETUP:-:}
67 TRACE=${TRACE:-""}
68 LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
69 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
70 . $LUSTRE/tests/test-framework.sh
71 init_test_env $@
72 . ${CONFIG:=$LUSTRE/tests/cfg/${NAME}.sh}
73
74 init_logging
75
76 #                                  5          12          (min)"
77 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 300o"
78
79 if [ "$mds1_FSTYPE" = "zfs" ]; then
80         # bug number for skipped test: LU-1957
81         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  180"
82         #                                               13    (min)"
83         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
84 fi
85
86 # Get the SLES distro version
87 #
88 # Returns a version string that should only be used in comparing
89 # strings returned by version_code()
90 sles_version_code()
91 {
92         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
93
94         # All SuSE Linux versions have one decimal. version_code expects two
95         local sles_version=$version.0
96         version_code $sles_version
97 }
98
99 # Check if we are running on Ubuntu or SLES so we can make decisions on
100 # what tests to run
101 if [ -r /etc/SuSE-release ]; then
102         sles_version=$(sles_version_code)
103         [ $sles_version -lt $(version_code 11.4.0) ] &&
104                 # bug number for skipped test: LU-4341
105                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
106         [ $sles_version -lt $(version_code 12.0.0) ] &&
107                 # bug number for skipped test: LU-3703
108                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
109 elif [ -r /etc/os-release ]; then
110         if grep -qi ubuntu /etc/os-release; then
111                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
112                                                 -e 's/^VERSION=//p' \
113                                                 /etc/os-release |
114                                                 awk '{ print $1 }'))
115
116                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
117                         # bug number for skipped test:
118                         #                LU-10334 LU-10366
119                         ALWAYS_EXCEPT+=" 103a     410"
120                 fi
121         fi
122 fi
123
124 FAIL_ON_ERROR=false
125
126 cleanup() {
127         echo -n "cln.."
128         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
129         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
130 }
131 setup() {
132         echo -n "mnt.."
133         load_modules
134         setupall || exit 10
135         echo "done"
136 }
137
138 check_swap_layouts_support()
139 {
140         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
141                 skip "Does not support layout lock."
142 }
143
144 check_and_setup_lustre
145 DIR=${DIR:-$MOUNT}
146 assert_DIR
147
148 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
149
150 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
151 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
152 rm -rf $DIR/[Rdfs][0-9]*
153
154 # $RUNAS_ID may get set incorrectly somewhere else
155 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
156         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
157
158 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
159
160 build_test_filter
161
162 if [ "${ONLY}" = "MOUNT" ] ; then
163         echo "Lustre is up, please go on"
164         exit
165 fi
166
167 echo "preparing for tests involving mounts"
168 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
169 touch $EXT2_DEV
170 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
171 echo # add a newline after mke2fs.
172
173 umask 077
174
175 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
176 lctl set_param debug=-1 2> /dev/null || true
177 test_0a() {
178         touch $DIR/$tfile
179         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
180         rm $DIR/$tfile
181         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
182 }
183 run_test 0a "touch; rm ====================="
184
185 test_0b() {
186         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
187         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
188 }
189 run_test 0b "chmod 0755 $DIR ============================="
190
191 test_0c() {
192         $LCTL get_param mdc.*.import | grep "state: FULL" ||
193                 error "import not FULL"
194         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
195                 error "bad target"
196 }
197 run_test 0c "check import proc"
198
199 test_0d() { # LU-3397
200         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
201                 skip "proc exports not supported before 2.10.57"
202
203         local mgs_exp="mgs.MGS.exports"
204         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
205         local exp_client_nid
206         local exp_client_version
207         local exp_val
208         local imp_val
209         local temp_imp=$DIR/$tfile.import
210         local temp_exp=$DIR/$tfile.export
211
212         # save mgc import file to $temp_imp
213         $LCTL get_param mgc.*.import | tee $temp_imp
214         # Check if client uuid is found in MGS export
215         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
216                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
217                         $client_uuid ] &&
218                         break;
219         done
220         # save mgs export file to $temp_exp
221         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
222
223         # Compare the value of field "connect_flags"
224         imp_val=$(grep "connect_flags" $temp_imp)
225         exp_val=$(grep "connect_flags" $temp_exp)
226         [ "$exp_val" == "$imp_val" ] ||
227                 error "export flags '$exp_val' != import flags '$imp_val'"
228
229         # Compare the value of client version
230         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
231         exp_val=$(version_code $exp_client_version)
232         imp_val=$CLIENT_VERSION
233         [ "$exp_val" == "$imp_val" ] ||
234                 error "export client version '$exp_val' != '$imp_val'"
235 }
236 run_test 0d "check export proc ============================="
237
238 test_1() {
239         test_mkdir $DIR/$tdir
240         test_mkdir $DIR/$tdir/d2
241         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
242         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
243         rmdir $DIR/$tdir/d2
244         rmdir $DIR/$tdir
245         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
246 }
247 run_test 1 "mkdir; remkdir; rmdir"
248
249 test_2() {
250         test_mkdir $DIR/$tdir
251         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
252         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
253         rm -r $DIR/$tdir
254         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
255 }
256 run_test 2 "mkdir; touch; rmdir; check file"
257
258 test_3() {
259         test_mkdir $DIR/$tdir
260         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
261         touch $DIR/$tdir/$tfile
262         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
263         rm -r $DIR/$tdir
264         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
265 }
266 run_test 3 "mkdir; touch; rmdir; check dir"
267
268 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
269 test_4() {
270         test_mkdir -i 1 $DIR/$tdir
271
272         touch $DIR/$tdir/$tfile ||
273                 error "Create file under remote directory failed"
274
275         rmdir $DIR/$tdir &&
276                 error "Expect error removing in-use dir $DIR/$tdir"
277
278         test -d $DIR/$tdir || error "Remote directory disappeared"
279
280         rm -rf $DIR/$tdir || error "remove remote dir error"
281 }
282 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
283
284 test_5() {
285         test_mkdir $DIR/$tdir
286         test_mkdir $DIR/$tdir/d2
287         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
288         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
289         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
290 }
291 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
292
293 test_6a() {
294         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
295         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
296         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
297                 error "$tfile does not have perm 0666 or UID $UID"
298         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
299         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
300                 error "$tfile should be 0666 and owned by UID $UID"
301 }
302 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
303
304 test_6c() {
305         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
306
307         touch $DIR/$tfile
308         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
309         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
310                 error "$tfile should be owned by UID $RUNAS_ID"
311         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
312         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
313                 error "$tfile should be owned by UID $RUNAS_ID"
314 }
315 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
316
317 test_6e() {
318         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
319
320         touch $DIR/$tfile
321         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
322         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
323                 error "$tfile should be owned by GID $UID"
324         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
325         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
326                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
327 }
328 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
329
330 test_6g() {
331         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
332
333         test_mkdir $DIR/$tdir
334         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
335         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
336         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
337         test_mkdir $DIR/$tdir/d/subdir
338         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
339                 error "$tdir/d/subdir should be GID $RUNAS_GID"
340         if [[ $MDSCOUNT -gt 1 ]]; then
341                 # check remote dir sgid inherite
342                 $LFS mkdir -i 0 $DIR/$tdir.local ||
343                         error "mkdir $tdir.local failed"
344                 chmod g+s $DIR/$tdir.local ||
345                         error "chmod $tdir.local failed"
346                 chgrp $RUNAS_GID $DIR/$tdir.local ||
347                         error "chgrp $tdir.local failed"
348                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
349                         error "mkdir $tdir.remote failed"
350                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
351                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
352                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
353                         error "$tdir.remote should be mode 02755"
354         fi
355 }
356 run_test 6g "verify new dir in sgid dir inherits group"
357
358 test_6h() { # bug 7331
359         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
360
361         touch $DIR/$tfile || error "touch failed"
362         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
363         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
364                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
365         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
366                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
367 }
368 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
369
370 test_7a() {
371         test_mkdir $DIR/$tdir
372         $MCREATE $DIR/$tdir/$tfile
373         chmod 0666 $DIR/$tdir/$tfile
374         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
375                 error "$tdir/$tfile should be mode 0666"
376 }
377 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
378
379 test_7b() {
380         if [ ! -d $DIR/$tdir ]; then
381                 test_mkdir $DIR/$tdir
382         fi
383         $MCREATE $DIR/$tdir/$tfile
384         echo -n foo > $DIR/$tdir/$tfile
385         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
386         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
387 }
388 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
389
390 test_8() {
391         test_mkdir $DIR/$tdir
392         touch $DIR/$tdir/$tfile
393         chmod 0666 $DIR/$tdir/$tfile
394         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
395                 error "$tfile mode not 0666"
396 }
397 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
398
399 test_9() {
400         test_mkdir $DIR/$tdir
401         test_mkdir $DIR/$tdir/d2
402         test_mkdir $DIR/$tdir/d2/d3
403         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
404 }
405 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
406
407 test_10() {
408         test_mkdir $DIR/$tdir
409         test_mkdir $DIR/$tdir/d2
410         touch $DIR/$tdir/d2/$tfile
411         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
412                 error "$tdir/d2/$tfile not a file"
413 }
414 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
415
416 test_11() {
417         test_mkdir $DIR/$tdir
418         test_mkdir $DIR/$tdir/d2
419         chmod 0666 $DIR/$tdir/d2
420         chmod 0705 $DIR/$tdir/d2
421         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
422                 error "$tdir/d2 mode not 0705"
423 }
424 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
425
426 test_12() {
427         test_mkdir $DIR/$tdir
428         touch $DIR/$tdir/$tfile
429         chmod 0666 $DIR/$tdir/$tfile
430         chmod 0654 $DIR/$tdir/$tfile
431         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
432                 error "$tdir/d2 mode not 0654"
433 }
434 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
435
436 test_13() {
437         test_mkdir $DIR/$tdir
438         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
439         >  $DIR/$tdir/$tfile
440         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
441                 error "$tdir/$tfile size not 0 after truncate"
442 }
443 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
444
445 test_14() {
446         test_mkdir $DIR/$tdir
447         touch $DIR/$tdir/$tfile
448         rm $DIR/$tdir/$tfile
449         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
450 }
451 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
452
453 test_15() {
454         test_mkdir $DIR/$tdir
455         touch $DIR/$tdir/$tfile
456         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
457         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
458                 error "$tdir/${tfile_2} not a file after rename"
459         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
460 }
461 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
462
463 test_16() {
464         test_mkdir $DIR/$tdir
465         touch $DIR/$tdir/$tfile
466         rm -rf $DIR/$tdir/$tfile
467         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
468 }
469 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
470
471 test_17a() {
472         test_mkdir $DIR/$tdir
473         touch $DIR/$tdir/$tfile
474         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
475         ls -l $DIR/$tdir
476         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
477                 error "$tdir/l-exist not a symlink"
478         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
479                 error "$tdir/l-exist not referencing a file"
480         rm -f $DIR/$tdir/l-exist
481         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
482 }
483 run_test 17a "symlinks: create, remove (real)"
484
485 test_17b() {
486         test_mkdir $DIR/$tdir
487         ln -s no-such-file $DIR/$tdir/l-dangle
488         ls -l $DIR/$tdir
489         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
490                 error "$tdir/l-dangle not referencing no-such-file"
491         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
492                 error "$tdir/l-dangle not referencing non-existent file"
493         rm -f $DIR/$tdir/l-dangle
494         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
495 }
496 run_test 17b "symlinks: create, remove (dangling)"
497
498 test_17c() { # bug 3440 - don't save failed open RPC for replay
499         test_mkdir $DIR/$tdir
500         ln -s foo $DIR/$tdir/$tfile
501         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
502 }
503 run_test 17c "symlinks: open dangling (should return error)"
504
505 test_17d() {
506         test_mkdir $DIR/$tdir
507         ln -s foo $DIR/$tdir/$tfile
508         touch $DIR/$tdir/$tfile || error "creating to new symlink"
509 }
510 run_test 17d "symlinks: create dangling"
511
512 test_17e() {
513         test_mkdir $DIR/$tdir
514         local foo=$DIR/$tdir/$tfile
515         ln -s $foo $foo || error "create symlink failed"
516         ls -l $foo || error "ls -l failed"
517         ls $foo && error "ls not failed" || true
518 }
519 run_test 17e "symlinks: create recursive symlink (should return error)"
520
521 test_17f() {
522         test_mkdir $DIR/$tdir
523         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
524         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
525         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
526         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
527         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
528         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
529         ls -l  $DIR/$tdir
530 }
531 run_test 17f "symlinks: long and very long symlink name"
532
533 # str_repeat(S, N) generate a string that is string S repeated N times
534 str_repeat() {
535         local s=$1
536         local n=$2
537         local ret=''
538         while [ $((n -= 1)) -ge 0 ]; do
539                 ret=$ret$s
540         done
541         echo $ret
542 }
543
544 # Long symlinks and LU-2241
545 test_17g() {
546         test_mkdir $DIR/$tdir
547         local TESTS="59 60 61 4094 4095"
548
549         # Fix for inode size boundary in 2.1.4
550         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
551                 TESTS="4094 4095"
552
553         # Patch not applied to 2.2 or 2.3 branches
554         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
555         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
556                 TESTS="4094 4095"
557
558         # skip long symlink name for rhel6.5.
559         # rhel6.5 has a limit (PATH_MAX - sizeof(struct filename))
560         grep -q '6.5' /etc/redhat-release &>/dev/null &&
561                 TESTS="59 60 61 4062 4063"
562
563         for i in $TESTS; do
564                 local SYMNAME=$(str_repeat 'x' $i)
565                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
566                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
567         done
568 }
569 run_test 17g "symlinks: really long symlink name and inode boundaries"
570
571 test_17h() { #bug 17378
572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
573         remote_mds_nodsh && skip "remote MDS with nodsh"
574
575         local mdt_idx
576
577         test_mkdir $DIR/$tdir
578         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
579         $LFS setstripe -c -1 $DIR/$tdir
580         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
581         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
582         touch $DIR/$tdir/$tfile || true
583 }
584 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
585
586 test_17i() { #bug 20018
587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
588         remote_mds_nodsh && skip "remote MDS with nodsh"
589
590         local foo=$DIR/$tdir/$tfile
591         local mdt_idx
592
593         test_mkdir -c1 $DIR/$tdir
594         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
595         ln -s $foo $foo || error "create symlink failed"
596 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
597         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
598         ls -l $foo && error "error not detected"
599         return 0
600 }
601 run_test 17i "don't panic on short symlink (should return error)"
602
603 test_17k() { #bug 22301
604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
605         [[ -z "$(which rsync 2>/dev/null)" ]] &&
606                 skip "no rsync command"
607         rsync --help | grep -q xattr ||
608                 skip_env "$(rsync --version | head -n1) does not support xattrs"
609         test_mkdir $DIR/$tdir
610         test_mkdir $DIR/$tdir.new
611         touch $DIR/$tdir/$tfile
612         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
613         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
614                 error "rsync failed with xattrs enabled"
615 }
616 run_test 17k "symlinks: rsync with xattrs enabled"
617
618 test_17l() { # LU-279
619         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
620                 skip "no getfattr command"
621
622         test_mkdir $DIR/$tdir
623         touch $DIR/$tdir/$tfile
624         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
625         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
626                 # -h to not follow symlinks. -m '' to list all the xattrs.
627                 # grep to remove first line: '# file: $path'.
628                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
629                 do
630                         lgetxattr_size_check $path $xattr ||
631                                 error "lgetxattr_size_check $path $xattr failed"
632                 done
633         done
634 }
635 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
636
637 # LU-1540
638 test_17m() {
639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
640         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
641         remote_mds_nodsh && skip "remote MDS with nodsh"
642         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
643         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
644                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
645
646         local short_sym="0123456789"
647         local wdir=$DIR/$tdir
648         local i
649
650         test_mkdir $wdir
651         long_sym=$short_sym
652         # create a long symlink file
653         for ((i = 0; i < 4; ++i)); do
654                 long_sym=${long_sym}${long_sym}
655         done
656
657         echo "create 512 short and long symlink files under $wdir"
658         for ((i = 0; i < 256; ++i)); do
659                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
660                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
661         done
662
663         echo "erase them"
664         rm -f $wdir/*
665         sync
666         wait_delete_completed
667
668         echo "recreate the 512 symlink files with a shorter string"
669         for ((i = 0; i < 512; ++i)); do
670                 # rewrite the symlink file with a shorter string
671                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
672                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
673         done
674
675         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
676         local devname=$(mdsdevname $mds_index)
677
678         echo "stop and checking mds${mds_index}:"
679         # e2fsck should not return error
680         stop mds${mds_index}
681         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
682         rc=$?
683
684         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
685                 error "start mds${mds_index} failed"
686         df $MOUNT > /dev/null 2>&1
687         [ $rc -eq 0 ] ||
688                 error "e2fsck detected error for short/long symlink: rc=$rc"
689         rm -f $wdir/*
690 }
691 run_test 17m "run e2fsck against MDT which contains short/long symlink"
692
693 check_fs_consistency_17n() {
694         local mdt_index
695         local rc=0
696
697         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
698         # so it only check MDT1/MDT2 instead of all of MDTs.
699         for mdt_index in 1 2; do
700                 local devname=$(mdsdevname $mdt_index)
701                 # e2fsck should not return error
702                 stop mds${mdt_index}
703                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
704                         rc=$((rc + $?))
705
706                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
707                         error "mount mds$mdt_index failed"
708                 df $MOUNT > /dev/null 2>&1
709         done
710         return $rc
711 }
712
713 test_17n() {
714         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
716         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
717         remote_mds_nodsh && skip "remote MDS with nodsh"
718         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
719         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
720                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
721
722         local i
723
724         test_mkdir $DIR/$tdir
725         for ((i=0; i<10; i++)); do
726                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
727                         error "create remote dir error $i"
728                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
729                         error "create files under remote dir failed $i"
730         done
731
732         check_fs_consistency_17n ||
733                 error "e2fsck report error after create files under remote dir"
734
735         for ((i = 0; i < 10; i++)); do
736                 rm -rf $DIR/$tdir/remote_dir_${i} ||
737                         error "destroy remote dir error $i"
738         done
739
740         check_fs_consistency_17n ||
741                 error "e2fsck report error after unlink files under remote dir"
742
743         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
744                 skip "lustre < 2.4.50 does not support migrate mv"
745
746         for ((i = 0; i < 10; i++)); do
747                 mkdir -p $DIR/$tdir/remote_dir_${i}
748                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
749                         error "create files under remote dir failed $i"
750                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
751                         error "migrate remote dir error $i"
752         done
753         check_fs_consistency_17n || error "e2fsck report error after migration"
754
755         for ((i = 0; i < 10; i++)); do
756                 rm -rf $DIR/$tdir/remote_dir_${i} ||
757                         error "destroy remote dir error $i"
758         done
759
760         check_fs_consistency_17n || error "e2fsck report error after unlink"
761 }
762 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
763
764 test_17o() {
765         remote_mds_nodsh && skip "remote MDS with nodsh"
766         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
767                 skip "Need MDS version at least 2.3.64"
768
769         local wdir=$DIR/${tdir}o
770         local mdt_index
771         local rc=0
772
773         test_mkdir $wdir
774         touch $wdir/$tfile
775         mdt_index=$($LFS getstripe -m $wdir/$tfile)
776         mdt_index=$((mdt_index + 1))
777
778         cancel_lru_locks mdc
779         #fail mds will wait the failover finish then set
780         #following fail_loc to avoid interfer the recovery process.
781         fail mds${mdt_index}
782
783         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
784         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
785         ls -l $wdir/$tfile && rc=1
786         do_facet mds${mdt_index} lctl set_param fail_loc=0
787         [[ $rc -eq 0 ]] || error "stat file should fail"
788 }
789 run_test 17o "stat file with incompat LMA feature"
790
791 test_18() {
792         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
793         ls $DIR || error "Failed to ls $DIR: $?"
794 }
795 run_test 18 "touch .../f ; ls ... =============================="
796
797 test_19a() {
798         touch $DIR/$tfile
799         ls -l $DIR
800         rm $DIR/$tfile
801         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
802 }
803 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
804
805 test_19b() {
806         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
807 }
808 run_test 19b "ls -l .../f19 (should return error) =============="
809
810 test_19c() {
811         [ $RUNAS_ID -eq $UID ] &&
812                 skip_env "RUNAS_ID = UID = $UID -- skipping"
813
814         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
815 }
816 run_test 19c "$RUNAS touch .../f19 (should return error) =="
817
818 test_19d() {
819         cat $DIR/f19 && error || true
820 }
821 run_test 19d "cat .../f19 (should return error) =============="
822
823 test_20() {
824         touch $DIR/$tfile
825         rm $DIR/$tfile
826         touch $DIR/$tfile
827         rm $DIR/$tfile
828         touch $DIR/$tfile
829         rm $DIR/$tfile
830         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
831 }
832 run_test 20 "touch .../f ; ls -l ..."
833
834 test_21() {
835         test_mkdir $DIR/$tdir
836         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
837         ln -s dangle $DIR/$tdir/link
838         echo foo >> $DIR/$tdir/link
839         cat $DIR/$tdir/dangle
840         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
841         $CHECKSTAT -f -t file $DIR/$tdir/link ||
842                 error "$tdir/link not linked to a file"
843 }
844 run_test 21 "write to dangling link"
845
846 test_22() {
847         local wdir=$DIR/$tdir
848         test_mkdir $wdir
849         chown $RUNAS_ID:$RUNAS_GID $wdir
850         (cd $wdir || error "cd $wdir failed";
851                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
852                 $RUNAS tar xf -)
853         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
854         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
855         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
856                 error "checkstat -u failed"
857 }
858 run_test 22 "unpack tar archive as non-root user"
859
860 # was test_23
861 test_23a() {
862         test_mkdir $DIR/$tdir
863         local file=$DIR/$tdir/$tfile
864
865         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
866         openfile -f O_CREAT:O_EXCL $file &&
867                 error "$file recreate succeeded" || true
868 }
869 run_test 23a "O_CREAT|O_EXCL in subdir"
870
871 test_23b() { # bug 18988
872         test_mkdir $DIR/$tdir
873         local file=$DIR/$tdir/$tfile
874
875         rm -f $file
876         echo foo > $file || error "write filed"
877         echo bar >> $file || error "append filed"
878         $CHECKSTAT -s 8 $file || error "wrong size"
879         rm $file
880 }
881 run_test 23b "O_APPEND check"
882
883 # LU-9409, size with O_APPEND and tiny writes
884 test_23c() {
885         local file=$DIR/$tfile
886
887         # single dd
888         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
889         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
890         rm -f $file
891
892         # racing tiny writes
893         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
894         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
895         wait
896         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
897         rm -f $file
898
899         #racing tiny & normal writes
900         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
901         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
902         wait
903         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
904         rm -f $file
905
906         #racing tiny & normal writes 2, ugly numbers
907         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
908         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
909         wait
910         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
911         rm -f $file
912 }
913 run_test 23c "O_APPEND size checks for tiny writes"
914
915 # LU-11069 file offset is correct after appending writes
916 test_23d() {
917         local file=$DIR/$tfile
918         local offset
919
920         echo CentaurHauls > $file
921         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
922         if ((offset != 26)); then
923                 error "wrong offset, expected 26, got '$offset'"
924         fi
925 }
926 run_test 23d "file offset is correct after appending writes"
927
928 # rename sanity
929 test_24a() {
930         echo '-- same directory rename'
931         test_mkdir $DIR/$tdir
932         touch $DIR/$tdir/$tfile.1
933         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
934         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
935 }
936 run_test 24a "rename file to non-existent target"
937
938 test_24b() {
939         test_mkdir $DIR/$tdir
940         touch $DIR/$tdir/$tfile.{1,2}
941         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
942         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
943         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
944 }
945 run_test 24b "rename file to existing target"
946
947 test_24c() {
948         test_mkdir $DIR/$tdir
949         test_mkdir $DIR/$tdir/d$testnum.1
950         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
951         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
952         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
953 }
954 run_test 24c "rename directory to non-existent target"
955
956 test_24d() {
957         test_mkdir -c1 $DIR/$tdir
958         test_mkdir -c1 $DIR/$tdir/d$testnum.1
959         test_mkdir -c1 $DIR/$tdir/d$testnum.2
960         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
961         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
962         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
963 }
964 run_test 24d "rename directory to existing target"
965
966 test_24e() {
967         echo '-- cross directory renames --'
968         test_mkdir $DIR/R5a
969         test_mkdir $DIR/R5b
970         touch $DIR/R5a/f
971         mv $DIR/R5a/f $DIR/R5b/g
972         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
973         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
974 }
975 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
976
977 test_24f() {
978         test_mkdir $DIR/R6a
979         test_mkdir $DIR/R6b
980         touch $DIR/R6a/f $DIR/R6b/g
981         mv $DIR/R6a/f $DIR/R6b/g
982         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
983         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
984 }
985 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
986
987 test_24g() {
988         test_mkdir $DIR/R7a
989         test_mkdir $DIR/R7b
990         test_mkdir $DIR/R7a/d
991         mv $DIR/R7a/d $DIR/R7b/e
992         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
993         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
994 }
995 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
996
997 test_24h() {
998         test_mkdir -c1 $DIR/R8a
999         test_mkdir -c1 $DIR/R8b
1000         test_mkdir -c1 $DIR/R8a/d
1001         test_mkdir -c1 $DIR/R8b/e
1002         mrename $DIR/R8a/d $DIR/R8b/e
1003         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1004         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1005 }
1006 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1007
1008 test_24i() {
1009         echo "-- rename error cases"
1010         test_mkdir $DIR/R9
1011         test_mkdir $DIR/R9/a
1012         touch $DIR/R9/f
1013         mrename $DIR/R9/f $DIR/R9/a
1014         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1015         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1016         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1017 }
1018 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1019
1020 test_24j() {
1021         test_mkdir $DIR/R10
1022         mrename $DIR/R10/f $DIR/R10/g
1023         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1024         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1025         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1026 }
1027 run_test 24j "source does not exist ============================"
1028
1029 test_24k() {
1030         test_mkdir $DIR/R11a
1031         test_mkdir $DIR/R11a/d
1032         touch $DIR/R11a/f
1033         mv $DIR/R11a/f $DIR/R11a/d
1034         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1035         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1036 }
1037 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1038
1039 # bug 2429 - rename foo foo foo creates invalid file
1040 test_24l() {
1041         f="$DIR/f24l"
1042         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1043 }
1044 run_test 24l "Renaming a file to itself ========================"
1045
1046 test_24m() {
1047         f="$DIR/f24m"
1048         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1049         # on ext3 this does not remove either the source or target files
1050         # though the "expected" operation would be to remove the source
1051         $CHECKSTAT -t file ${f} || error "${f} missing"
1052         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1053 }
1054 run_test 24m "Renaming a file to a hard link to itself ========="
1055
1056 test_24n() {
1057     f="$DIR/f24n"
1058     # this stats the old file after it was renamed, so it should fail
1059     touch ${f}
1060     $CHECKSTAT ${f} || error "${f} missing"
1061     mv ${f} ${f}.rename
1062     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1063     $CHECKSTAT -a ${f} || error "${f} exists"
1064 }
1065 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1066
1067 test_24o() {
1068         test_mkdir $DIR/$tdir
1069         rename_many -s random -v -n 10 $DIR/$tdir
1070 }
1071 run_test 24o "rename of files during htree split"
1072
1073 test_24p() {
1074         test_mkdir $DIR/R12a
1075         test_mkdir $DIR/R12b
1076         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1077         mrename $DIR/R12a $DIR/R12b
1078         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1079         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1080         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1081         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1082 }
1083 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1084
1085 cleanup_multiop_pause() {
1086         trap 0
1087         kill -USR1 $MULTIPID
1088 }
1089
1090 test_24q() {
1091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1092
1093         test_mkdir $DIR/R13a
1094         test_mkdir $DIR/R13b
1095         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1096         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1097         MULTIPID=$!
1098
1099         trap cleanup_multiop_pause EXIT
1100         mrename $DIR/R13a $DIR/R13b
1101         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1102         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1103         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1104         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1105         cleanup_multiop_pause
1106         wait $MULTIPID || error "multiop close failed"
1107 }
1108 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1109
1110 test_24r() { #bug 3789
1111         test_mkdir $DIR/R14a
1112         test_mkdir $DIR/R14a/b
1113         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1114         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1115         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1116 }
1117 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1118
1119 test_24s() {
1120         test_mkdir $DIR/R15a
1121         test_mkdir $DIR/R15a/b
1122         test_mkdir $DIR/R15a/b/c
1123         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1124         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1125         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1126 }
1127 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1128 test_24t() {
1129         test_mkdir $DIR/R16a
1130         test_mkdir $DIR/R16a/b
1131         test_mkdir $DIR/R16a/b/c
1132         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1133         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1134         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1135 }
1136 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1137
1138 test_24u() { # bug12192
1139         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1140         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1141 }
1142 run_test 24u "create stripe file"
1143
1144 simple_cleanup_common() {
1145         local rc=0
1146         trap 0
1147         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1148
1149         local start=$SECONDS
1150         rm -rf $DIR/$tdir
1151         rc=$?
1152         wait_delete_completed
1153         echo "cleanup time $((SECONDS - start))"
1154         return $rc
1155 }
1156
1157 max_pages_per_rpc() {
1158         local mdtname="$(printf "MDT%04x" ${1:-0})"
1159         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1160 }
1161
1162 test_24v() {
1163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1164
1165         local nrfiles=${COUNT:-100000}
1166         local fname="$DIR/$tdir/$tfile"
1167
1168         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1169         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1170
1171         test_mkdir "$(dirname $fname)"
1172         # assume MDT0000 has the fewest inodes
1173         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1174         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1175         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1176
1177         trap simple_cleanup_common EXIT
1178
1179         createmany -m "$fname" $nrfiles
1180
1181         cancel_lru_locks mdc
1182         lctl set_param mdc.*.stats clear
1183
1184         # was previously test_24D: LU-6101
1185         # readdir() returns correct number of entries after cursor reload
1186         local num_ls=$(ls $DIR/$tdir | wc -l)
1187         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1188         local num_all=$(ls -a $DIR/$tdir | wc -l)
1189         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1190                 [ $num_all -ne $((nrfiles + 2)) ]; then
1191                         error "Expected $nrfiles files, got $num_ls " \
1192                                 "($num_uniq unique $num_all .&..)"
1193         fi
1194         # LU-5 large readdir
1195         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1196         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1197         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1198         # take into account of overhead in lu_dirpage header and end mark in
1199         # each page, plus one in rpc_num calculation.
1200         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1201         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1202         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1203         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1204         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1205         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1206         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1207         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1208                 error "large readdir doesn't take effect: " \
1209                       "$mds_readpage should be about $rpc_max"
1210
1211         simple_cleanup_common
1212 }
1213 run_test 24v "list large directory (test hash collision, b=17560)"
1214
1215 test_24w() { # bug21506
1216         SZ1=234852
1217         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1218         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1219         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1220         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1221         [[ "$SZ1" -eq "$SZ2" ]] ||
1222                 error "Error reading at the end of the file $tfile"
1223 }
1224 run_test 24w "Reading a file larger than 4Gb"
1225
1226 test_24x() {
1227         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1229         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1230                 skip "Need MDS version at least 2.7.56"
1231
1232         local MDTIDX=1
1233         local remote_dir=$DIR/$tdir/remote_dir
1234
1235         test_mkdir $DIR/$tdir
1236         $LFS mkdir -i $MDTIDX $remote_dir ||
1237                 error "create remote directory failed"
1238
1239         test_mkdir $DIR/$tdir/src_dir
1240         touch $DIR/$tdir/src_file
1241         test_mkdir $remote_dir/tgt_dir
1242         touch $remote_dir/tgt_file
1243
1244         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1245                 error "rename dir cross MDT failed!"
1246
1247         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1248                 error "rename file cross MDT failed!"
1249
1250         touch $DIR/$tdir/ln_file
1251         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1252                 error "ln file cross MDT failed"
1253
1254         rm -rf $DIR/$tdir || error "Can not delete directories"
1255 }
1256 run_test 24x "cross MDT rename/link"
1257
1258 test_24y() {
1259         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1261
1262         local remote_dir=$DIR/$tdir/remote_dir
1263         local mdtidx=1
1264
1265         test_mkdir $DIR/$tdir
1266         $LFS mkdir -i $mdtidx $remote_dir ||
1267                 error "create remote directory failed"
1268
1269         test_mkdir $remote_dir/src_dir
1270         touch $remote_dir/src_file
1271         test_mkdir $remote_dir/tgt_dir
1272         touch $remote_dir/tgt_file
1273
1274         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1275                 error "rename subdir in the same remote dir failed!"
1276
1277         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1278                 error "rename files in the same remote dir failed!"
1279
1280         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1281                 error "link files in the same remote dir failed!"
1282
1283         rm -rf $DIR/$tdir || error "Can not delete directories"
1284 }
1285 run_test 24y "rename/link on the same dir should succeed"
1286
1287 test_24z() {
1288         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1289         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1290                 skip "Need MDS version at least 2.12.51"
1291
1292         local index
1293
1294         for index in 0 1; do
1295                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1296                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1297         done
1298
1299         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1300
1301         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1302         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1303
1304         local mdts=$(comma_list $(mdts_nodes))
1305
1306         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1307         stack_trap "do_nodes $mdts $LCTL \
1308                 set_param mdt.*.enable_remote_rename=1" EXIT
1309
1310         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1311
1312         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1313         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1314 }
1315 run_test 24z "cross-MDT rename is done as cp"
1316
1317 test_24A() { # LU-3182
1318         local NFILES=5000
1319
1320         rm -rf $DIR/$tdir
1321         test_mkdir $DIR/$tdir
1322         trap simple_cleanup_common EXIT
1323         createmany -m $DIR/$tdir/$tfile $NFILES
1324         local t=$(ls $DIR/$tdir | wc -l)
1325         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1326         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1327         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1328            [ $v -ne $((NFILES + 2)) ] ; then
1329                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1330         fi
1331
1332         simple_cleanup_common || error "Can not delete directories"
1333 }
1334 run_test 24A "readdir() returns correct number of entries."
1335
1336 test_24B() { # LU-4805
1337         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1338
1339         local count
1340
1341         test_mkdir $DIR/$tdir
1342         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1343                 error "create striped dir failed"
1344
1345         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1346         [ $count -eq 2 ] || error "Expected 2, got $count"
1347
1348         touch $DIR/$tdir/striped_dir/a
1349
1350         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1351         [ $count -eq 3 ] || error "Expected 3, got $count"
1352
1353         touch $DIR/$tdir/striped_dir/.f
1354
1355         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1356         [ $count -eq 4 ] || error "Expected 4, got $count"
1357
1358         rm -rf $DIR/$tdir || error "Can not delete directories"
1359 }
1360 run_test 24B "readdir for striped dir return correct number of entries"
1361
1362 test_24C() {
1363         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1364
1365         mkdir $DIR/$tdir
1366         mkdir $DIR/$tdir/d0
1367         mkdir $DIR/$tdir/d1
1368
1369         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1370                 error "create striped dir failed"
1371
1372         cd $DIR/$tdir/d0/striped_dir
1373
1374         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1375         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1376         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1377
1378         [ "$d0_ino" = "$parent_ino" ] ||
1379                 error ".. wrong, expect $d0_ino, get $parent_ino"
1380
1381         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1382                 error "mv striped dir failed"
1383
1384         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1385
1386         [ "$d1_ino" = "$parent_ino" ] ||
1387                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1388 }
1389 run_test 24C "check .. in striped dir"
1390
1391 test_24E() {
1392         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1394
1395         mkdir -p $DIR/$tdir
1396         mkdir $DIR/$tdir/src_dir
1397         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1398                 error "create remote source failed"
1399
1400         touch $DIR/$tdir/src_dir/src_child/a
1401
1402         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1403                 error "create remote target dir failed"
1404
1405         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1406                 error "create remote target child failed"
1407
1408         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1409                 error "rename dir cross MDT failed!"
1410
1411         find $DIR/$tdir
1412
1413         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1414                 error "src_child still exists after rename"
1415
1416         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1417                 error "missing file(a) after rename"
1418
1419         rm -rf $DIR/$tdir || error "Can not delete directories"
1420 }
1421 run_test 24E "cross MDT rename/link"
1422
1423 test_24F () {
1424         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1425
1426         local repeats=1000
1427         [ "$SLOW" = "no" ] && repeats=100
1428
1429         mkdir -p $DIR/$tdir
1430
1431         echo "$repeats repeats"
1432         for ((i = 0; i < repeats; i++)); do
1433                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1434                 touch $DIR/$tdir/test/a || error "touch fails"
1435                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1436                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1437         done
1438
1439         true
1440 }
1441 run_test 24F "hash order vs readdir (LU-11330)"
1442
1443 test_25a() {
1444         echo '== symlink sanity ============================================='
1445
1446         test_mkdir $DIR/d25
1447         ln -s d25 $DIR/s25
1448         touch $DIR/s25/foo ||
1449                 error "File creation in symlinked directory failed"
1450 }
1451 run_test 25a "create file in symlinked directory ==============="
1452
1453 test_25b() {
1454         [ ! -d $DIR/d25 ] && test_25a
1455         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1456 }
1457 run_test 25b "lookup file in symlinked directory ==============="
1458
1459 test_26a() {
1460         test_mkdir $DIR/d26
1461         test_mkdir $DIR/d26/d26-2
1462         ln -s d26/d26-2 $DIR/s26
1463         touch $DIR/s26/foo || error "File creation failed"
1464 }
1465 run_test 26a "multiple component symlink ======================="
1466
1467 test_26b() {
1468         test_mkdir -p $DIR/$tdir/d26-2
1469         ln -s $tdir/d26-2/foo $DIR/s26-2
1470         touch $DIR/s26-2 || error "File creation failed"
1471 }
1472 run_test 26b "multiple component symlink at end of lookup ======"
1473
1474 test_26c() {
1475         test_mkdir $DIR/d26.2
1476         touch $DIR/d26.2/foo
1477         ln -s d26.2 $DIR/s26.2-1
1478         ln -s s26.2-1 $DIR/s26.2-2
1479         ln -s s26.2-2 $DIR/s26.2-3
1480         chmod 0666 $DIR/s26.2-3/foo
1481 }
1482 run_test 26c "chain of symlinks"
1483
1484 # recursive symlinks (bug 439)
1485 test_26d() {
1486         ln -s d26-3/foo $DIR/d26-3
1487 }
1488 run_test 26d "create multiple component recursive symlink"
1489
1490 test_26e() {
1491         [ ! -h $DIR/d26-3 ] && test_26d
1492         rm $DIR/d26-3
1493 }
1494 run_test 26e "unlink multiple component recursive symlink"
1495
1496 # recursive symlinks (bug 7022)
1497 test_26f() {
1498         test_mkdir $DIR/$tdir
1499         test_mkdir $DIR/$tdir/$tfile
1500         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1501         test_mkdir -p lndir/bar1
1502         test_mkdir $DIR/$tdir/$tfile/$tfile
1503         cd $tfile                || error "cd $tfile failed"
1504         ln -s .. dotdot          || error "ln dotdot failed"
1505         ln -s dotdot/lndir lndir || error "ln lndir failed"
1506         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1507         output=`ls $tfile/$tfile/lndir/bar1`
1508         [ "$output" = bar1 ] && error "unexpected output"
1509         rm -r $tfile             || error "rm $tfile failed"
1510         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1511 }
1512 run_test 26f "rm -r of a directory which has recursive symlink"
1513
1514 test_27a() {
1515         test_mkdir $DIR/$tdir
1516         $LFS getstripe $DIR/$tdir
1517         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1518         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1519         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1520 }
1521 run_test 27a "one stripe file"
1522
1523 test_27b() {
1524         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1525
1526         test_mkdir $DIR/$tdir
1527         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1528         $LFS getstripe -c $DIR/$tdir/$tfile
1529         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1530                 error "two-stripe file doesn't have two stripes"
1531
1532         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1533 }
1534 run_test 27b "create and write to two stripe file"
1535
1536 # 27c family tests specific striping, setstripe -o
1537 test_27ca() {
1538         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1539         test_mkdir -p $DIR/$tdir
1540         local osts="1"
1541
1542         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1543         $LFS getstripe -i $DIR/$tdir/$tfile
1544         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1545                 error "stripe not on specified OST"
1546
1547         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1548 }
1549 run_test 27ca "one stripe on specified OST"
1550
1551 test_27cb() {
1552         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1553         test_mkdir -p $DIR/$tdir
1554         local osts="1,0"
1555         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1556         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1557         echo "$getstripe"
1558
1559         # Strip getstripe output to a space separated list of OSTs
1560         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1561                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1562         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1563                 error "stripes not on specified OSTs"
1564
1565         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1566 }
1567 run_test 27cb "two stripes on specified OSTs"
1568
1569 test_27cc() {
1570         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1571         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1572                 skip "server does not support overstriping"
1573
1574         test_mkdir -p $DIR/$tdir
1575         local osts="0,0"
1576         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1577         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1578         echo "$getstripe"
1579
1580         # Strip getstripe output to a space separated list of OSTs
1581         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1582                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1583         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1584                 error "stripes not on specified OSTs"
1585
1586         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1587 }
1588 run_test 27cc "two stripes on the same OST"
1589
1590 test_27cd() {
1591         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1592         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1593                 skip "server does not support overstriping"
1594         test_mkdir -p $DIR/$tdir
1595         local osts="0,1,1,0"
1596         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1597         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1598         echo "$getstripe"
1599
1600         # Strip getstripe output to a space separated list of OSTs
1601         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1602                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1603         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1604                 error "stripes not on specified OSTs"
1605
1606         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1607 }
1608 run_test 27cd "four stripes on two OSTs"
1609
1610 test_27ce() {
1611         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1612                 skip_env "too many osts, skipping"
1613         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1614                 skip "server does not support overstriping"
1615         # We do one more stripe than we have OSTs
1616         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1617                 skip_env "ea_inode feature disabled"
1618
1619         test_mkdir -p $DIR/$tdir
1620         local osts=""
1621         for i in $(seq 0 $OSTCOUNT);
1622         do
1623                 osts=$osts"0"
1624                 if [ $i -ne $OSTCOUNT ]; then
1625                         osts=$osts","
1626                 fi
1627         done
1628         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1629         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1630         echo "$getstripe"
1631
1632         # Strip getstripe output to a space separated list of OSTs
1633         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1634                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1635         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1636                 error "stripes not on specified OSTs"
1637
1638         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1639 }
1640 run_test 27ce "more stripes than OSTs with -o"
1641
1642 test_27d() {
1643         test_mkdir $DIR/$tdir
1644         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1645                 error "setstripe failed"
1646         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1647         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1648 }
1649 run_test 27d "create file with default settings"
1650
1651 test_27e() {
1652         # LU-5839 adds check for existed layout before setting it
1653         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1654                 skip "Need MDS version at least 2.7.56"
1655
1656         test_mkdir $DIR/$tdir
1657         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1658         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1659         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1660 }
1661 run_test 27e "setstripe existing file (should return error)"
1662
1663 test_27f() {
1664         test_mkdir $DIR/$tdir
1665         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1666                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1667         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1668                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1669         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1670         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1671 }
1672 run_test 27f "setstripe with bad stripe size (should return error)"
1673
1674 test_27g() {
1675         test_mkdir $DIR/$tdir
1676         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1677         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1678                 error "$DIR/$tdir/$tfile has object"
1679 }
1680 run_test 27g "$LFS getstripe with no objects"
1681
1682 test_27ga() {
1683         test_mkdir $DIR/$tdir
1684         touch $DIR/$tdir/$tfile || error "touch failed"
1685         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1686         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1687         local rc=$?
1688         (( rc == 2 )) || error "getstripe did not return ENOENT"
1689 }
1690 run_test 27ga "$LFS getstripe with missing file (should return error)"
1691
1692 test_27i() {
1693         test_mkdir $DIR/$tdir
1694         touch $DIR/$tdir/$tfile || error "touch failed"
1695         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1696                 error "missing objects"
1697 }
1698 run_test 27i "$LFS getstripe with some objects"
1699
1700 test_27j() {
1701         test_mkdir $DIR/$tdir
1702         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1703                 error "setstripe failed" || true
1704 }
1705 run_test 27j "setstripe with bad stripe offset (should return error)"
1706
1707 test_27k() { # bug 2844
1708         test_mkdir $DIR/$tdir
1709         local file=$DIR/$tdir/$tfile
1710         local ll_max_blksize=$((4 * 1024 * 1024))
1711         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1712         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1713         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1714         dd if=/dev/zero of=$file bs=4k count=1
1715         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1716         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1717 }
1718 run_test 27k "limit i_blksize for broken user apps"
1719
1720 test_27l() {
1721         mcreate $DIR/$tfile || error "creating file"
1722         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1723                 error "setstripe should have failed" || true
1724 }
1725 run_test 27l "check setstripe permissions (should return error)"
1726
1727 test_27m() {
1728         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1729
1730         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1731                 skip_env "multiple clients -- skipping"
1732
1733         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1734                    head -n1)
1735         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1736                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1737         fi
1738         trap simple_cleanup_common EXIT
1739         test_mkdir $DIR/$tdir
1740         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1741         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1742                 error "dd should fill OST0"
1743         i=2
1744         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1745                 i=$((i + 1))
1746                 [ $i -gt 256 ] && break
1747         done
1748         i=$((i + 1))
1749         touch $DIR/$tdir/$tfile.$i
1750         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1751             awk '{print $1}'| grep -w "0") ] &&
1752                 error "OST0 was full but new created file still use it"
1753         i=$((i + 1))
1754         touch $DIR/$tdir/$tfile.$i
1755         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1756             awk '{print $1}'| grep -w "0") ] &&
1757                 error "OST0 was full but new created file still use it"
1758         simple_cleanup_common
1759 }
1760 run_test 27m "create file while OST0 was full"
1761
1762 sleep_maxage() {
1763         local delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1764                       awk '{ print $1 * 2; exit; }')
1765         sleep $delay
1766 }
1767
1768 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1769 # if the OST isn't full anymore.
1770 reset_enospc() {
1771         local OSTIDX=${1:-""}
1772
1773         local list=$(comma_list $(osts_nodes))
1774         [ "$OSTIDX" ] && list=$(facet_host ost$((OSTIDX + 1)))
1775
1776         do_nodes $list lctl set_param fail_loc=0
1777         sync    # initiate all OST_DESTROYs from MDS to OST
1778         sleep_maxage
1779 }
1780
1781 exhaust_precreations() {
1782         local OSTIDX=$1
1783         local FAILLOC=$2
1784         local FAILIDX=${3:-$OSTIDX}
1785         local ofacet=ost$((OSTIDX + 1))
1786
1787         test_mkdir -p -c1 $DIR/$tdir
1788         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1789         local mfacet=mds$((mdtidx + 1))
1790         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1791
1792         local OST=$(ostname_from_index $OSTIDX)
1793
1794         # on the mdt's osc
1795         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1796         local last_id=$(do_facet $mfacet lctl get_param -n \
1797                         osc.$mdtosc_proc1.prealloc_last_id)
1798         local next_id=$(do_facet $mfacet lctl get_param -n \
1799                         osc.$mdtosc_proc1.prealloc_next_id)
1800
1801         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1802         do_facet $mfacet lctl get_param osc.$mdtosc_proc2.prealloc*
1803
1804         test_mkdir -p $DIR/$tdir/${OST}
1805         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1806 #define OBD_FAIL_OST_ENOSPC              0x215
1807         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1808         echo "Creating to objid $last_id on ost $OST..."
1809         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1810         do_facet $mfacet lctl get_param osc.$mdtosc_proc2.prealloc*
1811         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1812         sleep_maxage
1813 }
1814
1815 exhaust_all_precreations() {
1816         local i
1817         for (( i=0; i < OSTCOUNT; i++ )) ; do
1818                 exhaust_precreations $i $1 -1
1819         done
1820 }
1821
1822 test_27n() {
1823         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1825         remote_mds_nodsh && skip "remote MDS with nodsh"
1826         remote_ost_nodsh && skip "remote OST with nodsh"
1827
1828         reset_enospc
1829         rm -f $DIR/$tdir/$tfile
1830         exhaust_precreations 0 0x80000215
1831         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1832         touch $DIR/$tdir/$tfile || error "touch failed"
1833         $LFS getstripe $DIR/$tdir/$tfile
1834         reset_enospc
1835 }
1836 run_test 27n "create file with some full OSTs"
1837
1838 test_27o() {
1839         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1841         remote_mds_nodsh && skip "remote MDS with nodsh"
1842         remote_ost_nodsh && skip "remote OST with nodsh"
1843
1844         reset_enospc
1845         rm -f $DIR/$tdir/$tfile
1846         exhaust_all_precreations 0x215
1847
1848         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1849
1850         reset_enospc
1851         rm -rf $DIR/$tdir/*
1852 }
1853 run_test 27o "create file with all full OSTs (should error)"
1854
1855 test_27p() {
1856         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1858         remote_mds_nodsh && skip "remote MDS with nodsh"
1859         remote_ost_nodsh && skip "remote OST with nodsh"
1860
1861         reset_enospc
1862         rm -f $DIR/$tdir/$tfile
1863         test_mkdir $DIR/$tdir
1864
1865         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1866         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1867         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1868
1869         exhaust_precreations 0 0x80000215
1870         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1871         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1872         $LFS getstripe $DIR/$tdir/$tfile
1873
1874         reset_enospc
1875 }
1876 run_test 27p "append to a truncated file with some full OSTs"
1877
1878 test_27q() {
1879         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1881         remote_mds_nodsh && skip "remote MDS with nodsh"
1882         remote_ost_nodsh && skip "remote OST with nodsh"
1883
1884         reset_enospc
1885         rm -f $DIR/$tdir/$tfile
1886
1887         test_mkdir $DIR/$tdir
1888         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1889         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1890                 error "truncate $DIR/$tdir/$tfile failed"
1891         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1892
1893         exhaust_all_precreations 0x215
1894
1895         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1896         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1897
1898         reset_enospc
1899 }
1900 run_test 27q "append to truncated file with all OSTs full (should error)"
1901
1902 test_27r() {
1903         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1905         remote_mds_nodsh && skip "remote MDS with nodsh"
1906         remote_ost_nodsh && skip "remote OST with nodsh"
1907
1908         reset_enospc
1909         rm -f $DIR/$tdir/$tfile
1910         exhaust_precreations 0 0x80000215
1911
1912         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1913
1914         reset_enospc
1915 }
1916 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1917
1918 test_27s() { # bug 10725
1919         test_mkdir $DIR/$tdir
1920         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1921         local stripe_count=0
1922         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1923         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1924                 error "stripe width >= 2^32 succeeded" || true
1925
1926 }
1927 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1928
1929 test_27t() { # bug 10864
1930         WDIR=$(pwd)
1931         WLFS=$(which lfs)
1932         cd $DIR
1933         touch $tfile
1934         $WLFS getstripe $tfile
1935         cd $WDIR
1936 }
1937 run_test 27t "check that utils parse path correctly"
1938
1939 test_27u() { # bug 4900
1940         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1941         remote_mds_nodsh && skip "remote MDS with nodsh"
1942
1943         local index
1944         local list=$(comma_list $(mdts_nodes))
1945
1946 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1947         do_nodes $list $LCTL set_param fail_loc=0x139
1948         test_mkdir -p $DIR/$tdir
1949         trap simple_cleanup_common EXIT
1950         createmany -o $DIR/$tdir/t- 1000
1951         do_nodes $list $LCTL set_param fail_loc=0
1952
1953         TLOG=$TMP/$tfile.getstripe
1954         $LFS getstripe $DIR/$tdir > $TLOG
1955         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1956         unlinkmany $DIR/$tdir/t- 1000
1957         trap 0
1958         [[ $OBJS -gt 0 ]] &&
1959                 error "$OBJS objects created on OST-0. See $TLOG" ||
1960                 rm -f $TLOG
1961 }
1962 run_test 27u "skip object creation on OSC w/o objects"
1963
1964 test_27v() { # bug 4900
1965         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1967         remote_mds_nodsh && skip "remote MDS with nodsh"
1968         remote_ost_nodsh && skip "remote OST with nodsh"
1969
1970         exhaust_all_precreations 0x215
1971         reset_enospc
1972
1973         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1974
1975         touch $DIR/$tdir/$tfile
1976         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
1977         # all except ost1
1978         for (( i=1; i < OSTCOUNT; i++ )); do
1979                 do_facet ost$i lctl set_param fail_loc=0x705
1980         done
1981         local START=`date +%s`
1982         createmany -o $DIR/$tdir/$tfile 32
1983
1984         local FINISH=`date +%s`
1985         local TIMEOUT=`lctl get_param -n timeout`
1986         local PROCESS=$((FINISH - START))
1987         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
1988                error "$FINISH - $START >= $TIMEOUT / 2"
1989         sleep $((TIMEOUT / 2 - PROCESS))
1990         reset_enospc
1991 }
1992 run_test 27v "skip object creation on slow OST"
1993
1994 test_27w() { # bug 10997
1995         test_mkdir $DIR/$tdir
1996         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
1997         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
1998                 error "stripe size $size != 65536" || true
1999         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2000                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2001 }
2002 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2003
2004 test_27wa() {
2005         [[ $OSTCOUNT -lt 2 ]] &&
2006                 skip_env "skipping multiple stripe count/offset test"
2007
2008         test_mkdir $DIR/$tdir
2009         for i in $(seq 1 $OSTCOUNT); do
2010                 offset=$((i - 1))
2011                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2012                         error "setstripe -c $i -i $offset failed"
2013                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2014                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2015                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2016                 [ $index -ne $offset ] &&
2017                         error "stripe offset $index != $offset" || true
2018         done
2019 }
2020 run_test 27wa "check $LFS setstripe -c -i options"
2021
2022 test_27x() {
2023         remote_ost_nodsh && skip "remote OST with nodsh"
2024         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2026
2027         OFFSET=$(($OSTCOUNT - 1))
2028         OSTIDX=0
2029         local OST=$(ostname_from_index $OSTIDX)
2030
2031         test_mkdir $DIR/$tdir
2032         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2033         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2034         sleep_maxage
2035         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2036         for i in $(seq 0 $OFFSET); do
2037                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2038                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2039                 error "OST0 was degraded but new created file still use it"
2040         done
2041         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2042 }
2043 run_test 27x "create files while OST0 is degraded"
2044
2045 test_27y() {
2046         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2047         remote_mds_nodsh && skip "remote MDS with nodsh"
2048         remote_ost_nodsh && skip "remote OST with nodsh"
2049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2050
2051         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2052         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2053                 osc.$mdtosc.prealloc_last_id)
2054         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2055                 osc.$mdtosc.prealloc_next_id)
2056         local fcount=$((last_id - next_id))
2057         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2058         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2059
2060         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2061                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2062         local OST_DEACTIVE_IDX=-1
2063         local OSC
2064         local OSTIDX
2065         local OST
2066
2067         for OSC in $MDS_OSCS; do
2068                 OST=$(osc_to_ost $OSC)
2069                 OSTIDX=$(index_from_ostuuid $OST)
2070                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2071                         OST_DEACTIVE_IDX=$OSTIDX
2072                 fi
2073                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2074                         echo $OSC "is Deactivated:"
2075                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2076                 fi
2077         done
2078
2079         OSTIDX=$(index_from_ostuuid $OST)
2080         test_mkdir $DIR/$tdir
2081         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2082
2083         for OSC in $MDS_OSCS; do
2084                 OST=$(osc_to_ost $OSC)
2085                 OSTIDX=$(index_from_ostuuid $OST)
2086                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2087                         echo $OST "is degraded:"
2088                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2089                                                 obdfilter.$OST.degraded=1
2090                 fi
2091         done
2092
2093         sleep_maxage
2094         createmany -o $DIR/$tdir/$tfile $fcount
2095
2096         for OSC in $MDS_OSCS; do
2097                 OST=$(osc_to_ost $OSC)
2098                 OSTIDX=$(index_from_ostuuid $OST)
2099                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2100                         echo $OST "is recovered from degraded:"
2101                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2102                                                 obdfilter.$OST.degraded=0
2103                 else
2104                         do_facet $SINGLEMDS lctl --device %$OSC activate
2105                 fi
2106         done
2107
2108         # all osp devices get activated, hence -1 stripe count restored
2109         local stripe_count=0
2110
2111         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2112         # devices get activated.
2113         sleep_maxage
2114         $LFS setstripe -c -1 $DIR/$tfile
2115         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2116         rm -f $DIR/$tfile
2117         [ $stripe_count -ne $OSTCOUNT ] &&
2118                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2119         return 0
2120 }
2121 run_test 27y "create files while OST0 is degraded and the rest inactive"
2122
2123 check_seq_oid()
2124 {
2125         log "check file $1"
2126
2127         lmm_count=$($LFS getstripe -c $1)
2128         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2129         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2130
2131         local old_ifs="$IFS"
2132         IFS=$'[:]'
2133         fid=($($LFS path2fid $1))
2134         IFS="$old_ifs"
2135
2136         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2137         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2138
2139         # compare lmm_seq and lu_fid->f_seq
2140         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2141         # compare lmm_object_id and lu_fid->oid
2142         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2143
2144         # check the trusted.fid attribute of the OST objects of the file
2145         local have_obdidx=false
2146         local stripe_nr=0
2147         $LFS getstripe $1 | while read obdidx oid hex seq; do
2148                 # skip lines up to and including "obdidx"
2149                 [ -z "$obdidx" ] && break
2150                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2151                 $have_obdidx || continue
2152
2153                 local ost=$((obdidx + 1))
2154                 local dev=$(ostdevname $ost)
2155                 local oid_hex
2156
2157                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2158
2159                 seq=$(echo $seq | sed -e "s/^0x//g")
2160                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2161                         oid_hex=$(echo $oid)
2162                 else
2163                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2164                 fi
2165                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2166
2167                 local ff=""
2168                 #
2169                 # Don't unmount/remount the OSTs if we don't need to do that.
2170                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2171                 # update too, until that use mount/ll_decode_filter_fid/mount.
2172                 # Re-enable when debugfs will understand new filter_fid.
2173                 #
2174                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2175                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2176                                 $dev 2>/dev/null" | grep "parent=")
2177                 fi
2178                 if [ -z "$ff" ]; then
2179                         stop ost$ost
2180                         mount_fstype ost$ost
2181                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2182                                 $(facet_mntpt ost$ost)/$obj_file)
2183                         unmount_fstype ost$ost
2184                         start ost$ost $dev $OST_MOUNT_OPTS
2185                         clients_up
2186                 fi
2187
2188                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2189
2190                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2191
2192                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2193                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2194                 #
2195                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2196                 #       stripe_size=1048576 component_id=1 component_start=0 \
2197                 #       component_end=33554432
2198                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2199                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2200                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2201                 local ff_pstripe
2202                 if grep -q 'stripe=' <<<$ff; then
2203                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2204                 else
2205                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2206                         # into f_ver in this case.  See comment on ff_parent.
2207                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2208                 fi
2209
2210                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2211                 [ $ff_pseq = $lmm_seq ] ||
2212                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2213                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2214                 [ $ff_poid = $lmm_oid ] ||
2215                         error "FF parent OID $ff_poid != $lmm_oid"
2216                 (($ff_pstripe == $stripe_nr)) ||
2217                         error "FF stripe $ff_pstripe != $stripe_nr"
2218
2219                 stripe_nr=$((stripe_nr + 1))
2220                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2221                         continue
2222                 if grep -q 'stripe_count=' <<<$ff; then
2223                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2224                                             -e 's/ .*//' <<<$ff)
2225                         [ $lmm_count = $ff_scnt ] ||
2226                                 error "FF stripe count $lmm_count != $ff_scnt"
2227                 fi
2228         done
2229 }
2230
2231 test_27z() {
2232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2233         remote_ost_nodsh && skip "remote OST with nodsh"
2234
2235         test_mkdir $DIR/$tdir
2236         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2237                 { error "setstripe -c -1 failed"; return 1; }
2238         # We need to send a write to every object to get parent FID info set.
2239         # This _should_ also work for setattr, but does not currently.
2240         # touch $DIR/$tdir/$tfile-1 ||
2241         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2242                 { error "dd $tfile-1 failed"; return 2; }
2243         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2244                 { error "setstripe -c -1 failed"; return 3; }
2245         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2246                 { error "dd $tfile-2 failed"; return 4; }
2247
2248         # make sure write RPCs have been sent to OSTs
2249         sync; sleep 5; sync
2250
2251         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2252         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2253 }
2254 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2255
2256 test_27A() { # b=19102
2257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2258
2259         save_layout_restore_at_exit $MOUNT
2260         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2261         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2262                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2263         local default_size=$($LFS getstripe -S $MOUNT)
2264         local default_offset=$($LFS getstripe -i $MOUNT)
2265         local dsize=$(do_facet $SINGLEMDS \
2266                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2267         [ $default_size -eq $dsize ] ||
2268                 error "stripe size $default_size != $dsize"
2269         [ $default_offset -eq -1 ] ||
2270                 error "stripe offset $default_offset != -1"
2271 }
2272 run_test 27A "check filesystem-wide default LOV EA values"
2273
2274 test_27B() { # LU-2523
2275         test_mkdir $DIR/$tdir
2276         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2277         touch $DIR/$tdir/f0
2278         # open f1 with O_LOV_DELAY_CREATE
2279         # rename f0 onto f1
2280         # call setstripe ioctl on open file descriptor for f1
2281         # close
2282         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2283                 $DIR/$tdir/f0
2284
2285         rm -f $DIR/$tdir/f1
2286         # open f1 with O_LOV_DELAY_CREATE
2287         # unlink f1
2288         # call setstripe ioctl on open file descriptor for f1
2289         # close
2290         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2291
2292         # Allow multiop to fail in imitation of NFS's busted semantics.
2293         true
2294 }
2295 run_test 27B "call setstripe on open unlinked file/rename victim"
2296
2297 # 27C family tests full striping and overstriping
2298 test_27Ca() { #LU-2871
2299         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2300
2301         declare -a ost_idx
2302         local index
2303         local found
2304         local i
2305         local j
2306
2307         test_mkdir $DIR/$tdir
2308         cd $DIR/$tdir
2309         for i in $(seq 0 $((OSTCOUNT - 1))); do
2310                 # set stripe across all OSTs starting from OST$i
2311                 $LFS setstripe -i $i -c -1 $tfile$i
2312                 # get striping information
2313                 ost_idx=($($LFS getstripe $tfile$i |
2314                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2315                 echo ${ost_idx[@]}
2316
2317                 # check the layout
2318                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2319                         error "${#ost_idx[@]} != $OSTCOUNT"
2320
2321                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2322                         found=0
2323                         for j in $(echo ${ost_idx[@]}); do
2324                                 if [ $index -eq $j ]; then
2325                                         found=1
2326                                         break
2327                                 fi
2328                         done
2329                         [ $found = 1 ] ||
2330                                 error "Can not find $index in ${ost_idx[@]}"
2331                 done
2332         done
2333 }
2334 run_test 27Ca "check full striping across all OSTs"
2335
2336 test_27Cb() {
2337         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2338                 skip "server does not support overstriping"
2339         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2340                 skip_env "too many osts, skipping"
2341
2342         test_mkdir -p $DIR/$tdir
2343         local setcount=$(($OSTCOUNT * 2))
2344         [ $setcount -ge 160 ] || large_xattr_enabled ||
2345                 skip_env "ea_inode feature disabled"
2346
2347         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2348                 error "setstripe failed"
2349
2350         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2351         [ $count -eq $setcount ] ||
2352                 error "stripe count $count, should be $setcount"
2353
2354         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2355                 error "overstriped should be set in pattern"
2356
2357         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2358                 error "dd failed"
2359 }
2360 run_test 27Cb "more stripes than OSTs with -C"
2361
2362 test_27Cc() {
2363         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2364                 skip "server does not support overstriping"
2365         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2366
2367         test_mkdir -p $DIR/$tdir
2368         local setcount=$(($OSTCOUNT - 1))
2369
2370         [ $setcount -ge 160 ] || large_xattr_enabled ||
2371                 skip_env "ea_inode feature disabled"
2372
2373         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2374                 error "setstripe failed"
2375
2376         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2377         [ $count -eq $setcount ] ||
2378                 error "stripe count $count, should be $setcount"
2379
2380         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2381                 error "overstriped should not be set in pattern"
2382
2383         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2384                 error "dd failed"
2385 }
2386 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2387
2388 test_27Cd() {
2389         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2390                 skip "server does not support overstriping"
2391         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2392         large_xattr_enabled || skip_env "ea_inode feature disabled"
2393
2394         test_mkdir -p $DIR/$tdir
2395         local setcount=$LOV_MAX_STRIPE_COUNT
2396
2397         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2398                 error "setstripe failed"
2399
2400         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2401         [ $count -eq $setcount ] ||
2402                 error "stripe count $count, should be $setcount"
2403
2404         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2405                 error "overstriped should be set in pattern"
2406
2407         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2408                 error "dd failed"
2409
2410         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2411 }
2412 run_test 27Cd "test maximum stripe count"
2413
2414 test_27Ce() {
2415         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2416                 skip "server does not support overstriping"
2417         test_mkdir -p $DIR/$tdir
2418
2419         pool_add $TESTNAME || error "Pool creation failed"
2420         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2421
2422         local setcount=8
2423
2424         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2425                 error "setstripe failed"
2426
2427         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2428         [ $count -eq $setcount ] ||
2429                 error "stripe count $count, should be $setcount"
2430
2431         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2432                 error "overstriped should be set in pattern"
2433
2434         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2435                 error "dd failed"
2436
2437         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2438 }
2439 run_test 27Ce "test pool with overstriping"
2440
2441 test_27Cf() {
2442         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2443                 skip "server does not support overstriping"
2444         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2445                 skip_env "too many osts, skipping"
2446
2447         test_mkdir -p $DIR/$tdir
2448
2449         local setcount=$(($OSTCOUNT * 2))
2450         [ $setcount -ge 160 ] || large_xattr_enabled ||
2451                 skip_env "ea_inode feature disabled"
2452
2453         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2454                 error "setstripe failed"
2455
2456         echo 1 > $DIR/$tdir/$tfile
2457
2458         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2459         [ $count -eq $setcount ] ||
2460                 error "stripe count $count, should be $setcount"
2461
2462         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2463                 error "overstriped should be set in pattern"
2464
2465         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2466                 error "dd failed"
2467
2468         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2469 }
2470 run_test 27Cf "test default inheritance with overstriping"
2471
2472 test_27D() {
2473         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2474         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2475         remote_mds_nodsh && skip "remote MDS with nodsh"
2476
2477         local POOL=${POOL:-testpool}
2478         local first_ost=0
2479         local last_ost=$(($OSTCOUNT - 1))
2480         local ost_step=1
2481         local ost_list=$(seq $first_ost $ost_step $last_ost)
2482         local ost_range="$first_ost $last_ost $ost_step"
2483
2484         if ! combined_mgs_mds ; then
2485                 mount_mgs_client
2486         fi
2487
2488         test_mkdir $DIR/$tdir
2489         pool_add $POOL || error "pool_add failed"
2490         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2491
2492         local skip27D
2493         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2494                 skip27D+="-s 29"
2495         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2496                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2497                         skip27D+=" -s 30,31"
2498         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2499           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2500                 skip27D+=" -s 32,33"
2501         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2502                 error "llapi_layout_test failed"
2503
2504         destroy_test_pools || error "destroy test pools failed"
2505
2506         if ! combined_mgs_mds ; then
2507                 umount_mgs_client
2508         fi
2509 }
2510 run_test 27D "validate llapi_layout API"
2511
2512 # Verify that default_easize is increased from its initial value after
2513 # accessing a widely striped file.
2514 test_27E() {
2515         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2516         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2517                 skip "client does not have LU-3338 fix"
2518
2519         # 72 bytes is the minimum space required to store striping
2520         # information for a file striped across one OST:
2521         # (sizeof(struct lov_user_md_v3) +
2522         #  sizeof(struct lov_user_ost_data_v1))
2523         local min_easize=72
2524         $LCTL set_param -n llite.*.default_easize $min_easize ||
2525                 error "lctl set_param failed"
2526         local easize=$($LCTL get_param -n llite.*.default_easize)
2527
2528         [ $easize -eq $min_easize ] ||
2529                 error "failed to set default_easize"
2530
2531         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2532                 error "setstripe failed"
2533         cat $DIR/$tfile
2534         rm $DIR/$tfile
2535
2536         easize=$($LCTL get_param -n llite.*.default_easize)
2537
2538         [ $easize -gt $min_easize ] ||
2539                 error "default_easize not updated"
2540 }
2541 run_test 27E "check that default extended attribute size properly increases"
2542
2543 test_27F() { # LU-5346/LU-7975
2544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2545         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2546         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2547                 skip "Need MDS version at least 2.8.51"
2548         remote_ost_nodsh && skip "remote OST with nodsh"
2549
2550         test_mkdir $DIR/$tdir
2551         rm -f $DIR/$tdir/f0
2552         $LFS setstripe -c 2 $DIR/$tdir
2553
2554         # stop all OSTs to reproduce situation for LU-7975 ticket
2555         for num in $(seq $OSTCOUNT); do
2556                 stop ost$num
2557         done
2558
2559         # open/create f0 with O_LOV_DELAY_CREATE
2560         # truncate f0 to a non-0 size
2561         # close
2562         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2563
2564         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2565         # open/write it again to force delayed layout creation
2566         cat /etc/hosts > $DIR/$tdir/f0 &
2567         catpid=$!
2568
2569         # restart OSTs
2570         for num in $(seq $OSTCOUNT); do
2571                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2572                         error "ost$num failed to start"
2573         done
2574
2575         wait $catpid || error "cat failed"
2576
2577         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2578         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2579                 error "wrong stripecount"
2580
2581 }
2582 run_test 27F "Client resend delayed layout creation with non-zero size"
2583
2584 test_27G() { #LU-10629
2585         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2586                 skip "Need MDS version at least 2.11.51"
2587         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2588         remote_mds_nodsh && skip "remote MDS with nodsh"
2589         local POOL=${POOL:-testpool}
2590         local ostrange="0 0 1"
2591
2592         test_mkdir $DIR/$tdir
2593         pool_add $POOL || error "pool_add failed"
2594         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2595         $LFS setstripe -p $POOL $DIR/$tdir
2596
2597         local pool=$($LFS getstripe -p $DIR/$tdir)
2598
2599         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2600
2601         $LFS setstripe -d $DIR/$tdir
2602
2603         pool=$($LFS getstripe -p $DIR/$tdir)
2604
2605         rmdir $DIR/$tdir
2606
2607         [ -z "$pool" ] || error "'$pool' is not empty"
2608 }
2609 run_test 27G "Clear OST pool from stripe"
2610
2611 test_27H() {
2612         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2613                 skip "Need MDS version newer than 2.11.54"
2614         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2615         test_mkdir $DIR/$tdir
2616         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2617         touch $DIR/$tdir/$tfile
2618         $LFS getstripe -c $DIR/$tdir/$tfile
2619         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2620                 error "two-stripe file doesn't have two stripes"
2621
2622         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2623         $LFS getstripe -y $DIR/$tdir/$tfile
2624         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2625              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2626                 error "expected l_ost_idx: [02]$ not matched"
2627
2628         # make sure ost list has been cleared
2629         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2630         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2631                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2632         touch $DIR/$tdir/f3
2633         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2634 }
2635 run_test 27H "Set specific OSTs stripe"
2636
2637 test_27I() {
2638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2639         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2640         local pool=$TESTNAME
2641         local ostrange="1 1 1"
2642
2643         save_layout_restore_at_exit $MOUNT
2644         $LFS setstripe -c 2 -i 0 $MOUNT
2645         pool_add $pool || error "pool_add failed"
2646         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2647         test_mkdir $DIR/$tdir
2648         $LFS setstripe -p $pool $DIR/$tdir
2649         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2650         $LFS getstripe $DIR/$tdir/$tfile
2651 }
2652 run_test 27I "check that root dir striping does not break parent dir one"
2653
2654 test_27J() {
2655         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
2656                 skip "Need MDS version newer than 2.12.51"
2657
2658         test_mkdir $DIR/$tdir
2659         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2660         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2661
2662         # create foreign file (raw way)
2663         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2664                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2665
2666         # verify foreign file (raw way)
2667         parse_foreign_file -f $DIR/$tdir/$tfile |
2668                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2669                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2670         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2671                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2672         parse_foreign_file -f $DIR/$tdir/$tfile |
2673                 grep "lov_foreign_size: 73" ||
2674                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2675         parse_foreign_file -f $DIR/$tdir/$tfile |
2676                 grep "lov_foreign_type: 1" ||
2677                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2678         parse_foreign_file -f $DIR/$tdir/$tfile |
2679                 grep "lov_foreign_flags: 0x0000DA08" ||
2680                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2681         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2682                 grep "lov_foreign_value: 0x" |
2683                 sed -e 's/lov_foreign_value: 0x//')
2684         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2685         [[ $lov = ${lov2// /} ]] ||
2686                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2687
2688         # create foreign file (lfs + API)
2689         $LFS setstripe --foreign=daos --flags 0xda08 \
2690                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2691                 error "$DIR/$tdir/${tfile}2: create failed"
2692
2693         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2694                 grep "lfm_magic:.*0x0BD70BD0" ||
2695                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2696         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2697         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2698                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2699         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2700                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2701         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2702                 grep "lfm_flags:.*0x0000DA08" ||
2703                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2704         $LFS getstripe $DIR/$tdir/${tfile}2 |
2705                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2706                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2707
2708         # modify striping should fail
2709         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2710                 error "$DIR/$tdir/$tfile: setstripe should fail"
2711         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2712                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2713
2714         # R/W should fail
2715         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2716         cat $DIR/$tdir/${tfile}2 &&
2717                 error "$DIR/$tdir/${tfile}2: read should fail"
2718         cat /etc/passwd > $DIR/$tdir/$tfile &&
2719                 error "$DIR/$tdir/$tfile: write should fail"
2720         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2721                 error "$DIR/$tdir/${tfile}2: write should fail"
2722
2723         # chmod should work
2724         chmod 222 $DIR/$tdir/$tfile ||
2725                 error "$DIR/$tdir/$tfile: chmod failed"
2726         chmod 222 $DIR/$tdir/${tfile}2 ||
2727                 error "$DIR/$tdir/${tfile}2: chmod failed"
2728
2729         # chown should work
2730         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2731                 error "$DIR/$tdir/$tfile: chown failed"
2732         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2733                 error "$DIR/$tdir/${tfile}2: chown failed"
2734
2735         # rename should work
2736         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2737                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2738         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2739                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2740
2741         #remove foreign file
2742         rm $DIR/$tdir/${tfile}.new ||
2743                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2744         rm $DIR/$tdir/${tfile}2.new ||
2745                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2746 }
2747 run_test 27J "basic ops on file with foreign LOV"
2748
2749 test_27K() {
2750         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
2751                 skip "Need MDS version newer than 2.12.49"
2752
2753         test_mkdir $DIR/$tdir
2754         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2755         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2756
2757         # create foreign dir (raw way)
2758         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2759                 error "create_foreign_dir FAILED"
2760
2761         # verify foreign dir (raw way)
2762         parse_foreign_dir -d $DIR/$tdir/$tdir |
2763                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2764                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2765         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2766                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2767         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2768                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2769         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2770                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2771         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2772                 grep "lmv_foreign_value: 0x" |
2773                 sed 's/lmv_foreign_value: 0x//')
2774         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2775                 sed 's/ //g')
2776         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2777
2778         # create foreign dir (lfs + API)
2779         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2780                 $DIR/$tdir/${tdir}2 ||
2781                 error "$DIR/$tdir/${tdir}2: create failed"
2782
2783         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2784                 grep "lfm_magic:.*0x0CD50CD0" ||
2785                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2786         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2787         # - sizeof(lfm_type) - sizeof(lfm_flags)
2788         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2789                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2790         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2791                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2792         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2793                 grep "lfm_flags:.*0x0000DA05" ||
2794                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2795         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2796                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2797                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2798
2799         # file create in dir should fail
2800         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2801         touch $DIR/$tdir/${tdir}2/$tfile &&
2802                 "$DIR/${tdir}2: file create should fail"
2803
2804         # chmod should work
2805         chmod 777 $DIR/$tdir/$tdir ||
2806                 error "$DIR/$tdir: chmod failed"
2807         chmod 777 $DIR/$tdir/${tdir}2 ||
2808                 error "$DIR/${tdir}2: chmod failed"
2809
2810         # chown should work
2811         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2812                 error "$DIR/$tdir: chown failed"
2813         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2814                 error "$DIR/${tdir}2: chown failed"
2815
2816         # rename should work
2817         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2818                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2819         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2820                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2821
2822         #remove foreign dir
2823         rmdir $DIR/$tdir/${tdir}.new ||
2824                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2825         rmdir $DIR/$tdir/${tdir}2.new ||
2826                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2827 }
2828 run_test 27K "basic ops on dir with foreign LMV"
2829
2830 # createtest also checks that device nodes are created and
2831 # then visible correctly (#2091)
2832 test_28() { # bug 2091
2833         test_mkdir $DIR/d28
2834         $CREATETEST $DIR/d28/ct || error "createtest failed"
2835 }
2836 run_test 28 "create/mknod/mkdir with bad file types ============"
2837
2838 test_29() {
2839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2840
2841         sync; sleep 1; sync # flush out any dirty pages from previous tests
2842         cancel_lru_locks
2843         test_mkdir $DIR/d29
2844         touch $DIR/d29/foo
2845         log 'first d29'
2846         ls -l $DIR/d29
2847
2848         declare -i LOCKCOUNTORIG=0
2849         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2850                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
2851         done
2852         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
2853
2854         declare -i LOCKUNUSEDCOUNTORIG=0
2855         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2856                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
2857         done
2858
2859         log 'second d29'
2860         ls -l $DIR/d29
2861         log 'done'
2862
2863         declare -i LOCKCOUNTCURRENT=0
2864         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2865                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
2866         done
2867
2868         declare -i LOCKUNUSEDCOUNTCURRENT=0
2869         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2870                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
2871         done
2872
2873         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
2874                 $LCTL set_param -n ldlm.dump_namespaces ""
2875                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
2876                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2877                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2878                 return 2
2879         fi
2880         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
2881                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
2882                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2883                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2884                 return 3
2885         fi
2886 }
2887 run_test 29 "IT_GETATTR regression  ============================"
2888
2889 test_30a() { # was test_30
2890         cp $(which ls) $DIR || cp /bin/ls $DIR
2891         $DIR/ls / || error "Can't execute binary from lustre"
2892         rm $DIR/ls
2893 }
2894 run_test 30a "execute binary from Lustre (execve) =============="
2895
2896 test_30b() {
2897         cp `which ls` $DIR || cp /bin/ls $DIR
2898         chmod go+rx $DIR/ls
2899         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
2900         rm $DIR/ls
2901 }
2902 run_test 30b "execute binary from Lustre as non-root ==========="
2903
2904 test_30c() { # b=22376
2905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2906
2907         cp `which ls` $DIR || cp /bin/ls $DIR
2908         chmod a-rw $DIR/ls
2909         cancel_lru_locks mdc
2910         cancel_lru_locks osc
2911         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
2912         rm -f $DIR/ls
2913 }
2914 run_test 30c "execute binary from Lustre without read perms ===="
2915
2916 test_31a() {
2917         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
2918         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
2919 }
2920 run_test 31a "open-unlink file =================================="
2921
2922 test_31b() {
2923         touch $DIR/f31 || error "touch $DIR/f31 failed"
2924         ln $DIR/f31 $DIR/f31b || error "ln failed"
2925         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
2926         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
2927 }
2928 run_test 31b "unlink file with multiple links while open ======="
2929
2930 test_31c() {
2931         touch $DIR/f31 || error "touch $DIR/f31 failed"
2932         ln $DIR/f31 $DIR/f31c || error "ln failed"
2933         multiop_bg_pause $DIR/f31 O_uc ||
2934                 error "multiop_bg_pause for $DIR/f31 failed"
2935         MULTIPID=$!
2936         $MULTIOP $DIR/f31c Ouc
2937         kill -USR1 $MULTIPID
2938         wait $MULTIPID
2939 }
2940 run_test 31c "open-unlink file with multiple links ============="
2941
2942 test_31d() {
2943         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
2944         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
2945 }
2946 run_test 31d "remove of open directory ========================="
2947
2948 test_31e() { # bug 2904
2949         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
2950 }
2951 run_test 31e "remove of open non-empty directory ==============="
2952
2953 test_31f() { # bug 4554
2954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2955
2956         set -vx
2957         test_mkdir $DIR/d31f
2958         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2959         cp /etc/hosts $DIR/d31f
2960         ls -l $DIR/d31f
2961         $LFS getstripe $DIR/d31f/hosts
2962         multiop_bg_pause $DIR/d31f D_c || return 1
2963         MULTIPID=$!
2964
2965         rm -rv $DIR/d31f || error "first of $DIR/d31f"
2966         test_mkdir $DIR/d31f
2967         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2968         cp /etc/hosts $DIR/d31f
2969         ls -l $DIR/d31f
2970         $LFS getstripe $DIR/d31f/hosts
2971         multiop_bg_pause $DIR/d31f D_c || return 1
2972         MULTIPID2=$!
2973
2974         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
2975         wait $MULTIPID || error "first opendir $MULTIPID failed"
2976
2977         sleep 6
2978
2979         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
2980         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
2981         set +vx
2982 }
2983 run_test 31f "remove of open directory with open-unlink file ==="
2984
2985 test_31g() {
2986         echo "-- cross directory link --"
2987         test_mkdir -c1 $DIR/${tdir}ga
2988         test_mkdir -c1 $DIR/${tdir}gb
2989         touch $DIR/${tdir}ga/f
2990         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
2991         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
2992         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
2993         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
2994         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
2995 }
2996 run_test 31g "cross directory link==============="
2997
2998 test_31h() {
2999         echo "-- cross directory link --"
3000         test_mkdir -c1 $DIR/${tdir}
3001         test_mkdir -c1 $DIR/${tdir}/dir
3002         touch $DIR/${tdir}/f
3003         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3004         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3005         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3006         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3007         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3008 }
3009 run_test 31h "cross directory link under child==============="
3010
3011 test_31i() {
3012         echo "-- cross directory link --"
3013         test_mkdir -c1 $DIR/$tdir
3014         test_mkdir -c1 $DIR/$tdir/dir
3015         touch $DIR/$tdir/dir/f
3016         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3017         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3018         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3019         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3020         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3021 }
3022 run_test 31i "cross directory link under parent==============="
3023
3024 test_31j() {
3025         test_mkdir -c1 -p $DIR/$tdir
3026         test_mkdir -c1 -p $DIR/$tdir/dir1
3027         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3028         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3029         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3030         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3031         return 0
3032 }
3033 run_test 31j "link for directory==============="
3034
3035 test_31k() {
3036         test_mkdir -c1 -p $DIR/$tdir
3037         touch $DIR/$tdir/s
3038         touch $DIR/$tdir/exist
3039         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3040         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3041         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3042         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3043         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3044         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3045         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3046         return 0
3047 }
3048 run_test 31k "link to file: the same, non-existing, dir==============="
3049
3050 test_31m() {
3051         mkdir $DIR/d31m
3052         touch $DIR/d31m/s
3053         mkdir $DIR/d31m2
3054         touch $DIR/d31m2/exist
3055         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3056         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3057         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3058         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3059         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3060         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3061         return 0
3062 }
3063 run_test 31m "link to file: the same, non-existing, dir==============="
3064
3065 test_31n() {
3066         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3067         nlink=$(stat --format=%h $DIR/$tfile)
3068         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3069         local fd=$(free_fd)
3070         local cmd="exec $fd<$DIR/$tfile"
3071         eval $cmd
3072         cmd="exec $fd<&-"
3073         trap "eval $cmd" EXIT
3074         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3075         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3076         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3077         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3078         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3079         eval $cmd
3080 }
3081 run_test 31n "check link count of unlinked file"
3082
3083 link_one() {
3084         local TEMPNAME=$(mktemp $1_XXXXXX)
3085         mlink $TEMPNAME $1 2> /dev/null &&
3086                 echo "$BASHPID: link $TEMPNAME to $1 succeeded"
3087         munlink $TEMPNAME
3088 }
3089
3090 test_31o() { # LU-2901
3091         test_mkdir $DIR/$tdir
3092         for LOOP in $(seq 100); do
3093                 rm -f $DIR/$tdir/$tfile*
3094                 for THREAD in $(seq 8); do
3095                         link_one $DIR/$tdir/$tfile.$LOOP &
3096                 done
3097                 wait
3098                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3099                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3100                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3101                         break || true
3102         done
3103 }
3104 run_test 31o "duplicate hard links with same filename"
3105
3106 test_31p() {
3107         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3108
3109         test_mkdir $DIR/$tdir
3110         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3111         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3112
3113         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3114                 error "open unlink test1 failed"
3115         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3116                 error "open unlink test2 failed"
3117
3118         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3119                 error "test1 still exists"
3120         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3121                 error "test2 still exists"
3122 }
3123 run_test 31p "remove of open striped directory"
3124
3125 cleanup_test32_mount() {
3126         local rc=0
3127         trap 0
3128         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3129         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3130         losetup -d $loopdev || true
3131         rm -rf $DIR/$tdir
3132         return $rc
3133 }
3134
3135 test_32a() {
3136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3137
3138         echo "== more mountpoints and symlinks ================="
3139         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3140         trap cleanup_test32_mount EXIT
3141         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3142         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3143                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3144         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3145                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3146         cleanup_test32_mount
3147 }
3148 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3149
3150 test_32b() {
3151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3152
3153         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3154         trap cleanup_test32_mount EXIT
3155         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3156         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3157                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3158         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3159                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3160         cleanup_test32_mount
3161 }
3162 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3163
3164 test_32c() {
3165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3166
3167         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3168         trap cleanup_test32_mount EXIT
3169         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3170         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3171                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3172         test_mkdir -p $DIR/$tdir/d2/test_dir
3173         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3174                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3175         cleanup_test32_mount
3176 }
3177 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3178
3179 test_32d() {
3180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3181
3182         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3183         trap cleanup_test32_mount EXIT
3184         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3185         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3186                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3187         test_mkdir -p $DIR/$tdir/d2/test_dir
3188         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3189                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3190         cleanup_test32_mount
3191 }
3192 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3193
3194 test_32e() {
3195         rm -fr $DIR/$tdir
3196         test_mkdir -p $DIR/$tdir/tmp
3197         local tmp_dir=$DIR/$tdir/tmp
3198         ln -s $DIR/$tdir $tmp_dir/symlink11
3199         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3200         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3201         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3202 }
3203 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3204
3205 test_32f() {
3206         rm -fr $DIR/$tdir
3207         test_mkdir -p $DIR/$tdir/tmp
3208         local tmp_dir=$DIR/$tdir/tmp
3209         ln -s $DIR/$tdir $tmp_dir/symlink11
3210         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3211         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3212         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3213 }
3214 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3215
3216 test_32g() {
3217         local tmp_dir=$DIR/$tdir/tmp
3218         test_mkdir -p $tmp_dir
3219         test_mkdir $DIR/${tdir}2
3220         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3221         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3222         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3223         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3224         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3225         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3226 }
3227 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3228
3229 test_32h() {
3230         rm -fr $DIR/$tdir $DIR/${tdir}2
3231         tmp_dir=$DIR/$tdir/tmp
3232         test_mkdir -p $tmp_dir
3233         test_mkdir $DIR/${tdir}2
3234         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3235         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3236         ls $tmp_dir/symlink12 || error "listing symlink12"
3237         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3238 }
3239 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3240
3241 test_32i() {
3242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3243
3244         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3245         trap cleanup_test32_mount EXIT
3246         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3247         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3248                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3249         touch $DIR/$tdir/test_file
3250         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3251                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3252         cleanup_test32_mount
3253 }
3254 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3255
3256 test_32j() {
3257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3258
3259         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3260         trap cleanup_test32_mount EXIT
3261         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3262         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3263                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3264         touch $DIR/$tdir/test_file
3265         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3266                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3267         cleanup_test32_mount
3268 }
3269 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3270
3271 test_32k() {
3272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3273
3274         rm -fr $DIR/$tdir
3275         trap cleanup_test32_mount EXIT
3276         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3277         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3278                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3279         test_mkdir -p $DIR/$tdir/d2
3280         touch $DIR/$tdir/d2/test_file || error "touch failed"
3281         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3282                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3283         cleanup_test32_mount
3284 }
3285 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3286
3287 test_32l() {
3288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3289
3290         rm -fr $DIR/$tdir
3291         trap cleanup_test32_mount EXIT
3292         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3293         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3294                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3295         test_mkdir -p $DIR/$tdir/d2
3296         touch $DIR/$tdir/d2/test_file || error "touch failed"
3297         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3298                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3299         cleanup_test32_mount
3300 }
3301 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3302
3303 test_32m() {
3304         rm -fr $DIR/d32m
3305         test_mkdir -p $DIR/d32m/tmp
3306         TMP_DIR=$DIR/d32m/tmp
3307         ln -s $DIR $TMP_DIR/symlink11
3308         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3309         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3310                 error "symlink11 not a link"
3311         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3312                 error "symlink01 not a link"
3313 }
3314 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3315
3316 test_32n() {
3317         rm -fr $DIR/d32n
3318         test_mkdir -p $DIR/d32n/tmp
3319         TMP_DIR=$DIR/d32n/tmp
3320         ln -s $DIR $TMP_DIR/symlink11
3321         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3322         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3323         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3324 }
3325 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3326
3327 test_32o() {
3328         touch $DIR/$tfile
3329         test_mkdir -p $DIR/d32o/tmp
3330         TMP_DIR=$DIR/d32o/tmp
3331         ln -s $DIR/$tfile $TMP_DIR/symlink12
3332         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3333         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3334                 error "symlink12 not a link"
3335         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3336         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3337                 error "$DIR/d32o/tmp/symlink12 not file type"
3338         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3339                 error "$DIR/d32o/symlink02 not file type"
3340 }
3341 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3342
3343 test_32p() {
3344         log 32p_1
3345         rm -fr $DIR/d32p
3346         log 32p_2
3347         rm -f $DIR/$tfile
3348         log 32p_3
3349         touch $DIR/$tfile
3350         log 32p_4
3351         test_mkdir -p $DIR/d32p/tmp
3352         log 32p_5
3353         TMP_DIR=$DIR/d32p/tmp
3354         log 32p_6
3355         ln -s $DIR/$tfile $TMP_DIR/symlink12
3356         log 32p_7
3357         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3358         log 32p_8
3359         cat $DIR/d32p/tmp/symlink12 ||
3360                 error "Can't open $DIR/d32p/tmp/symlink12"
3361         log 32p_9
3362         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3363         log 32p_10
3364 }
3365 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3366
3367 test_32q() {
3368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3369
3370         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3371         trap cleanup_test32_mount EXIT
3372         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3373         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3374         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3375                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3376         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3377         cleanup_test32_mount
3378 }
3379 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3380
3381 test_32r() {
3382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3383
3384         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3385         trap cleanup_test32_mount EXIT
3386         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3387         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3388         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3389                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3390         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3391         cleanup_test32_mount
3392 }
3393 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3394
3395 test_33aa() {
3396         rm -f $DIR/$tfile
3397         touch $DIR/$tfile
3398         chmod 444 $DIR/$tfile
3399         chown $RUNAS_ID $DIR/$tfile
3400         log 33_1
3401         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3402         log 33_2
3403 }
3404 run_test 33aa "write file with mode 444 (should return error)"
3405
3406 test_33a() {
3407         rm -fr $DIR/$tdir
3408         test_mkdir $DIR/$tdir
3409         chown $RUNAS_ID $DIR/$tdir
3410         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3411                 error "$RUNAS create $tdir/$tfile failed"
3412         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3413                 error "open RDWR" || true
3414 }
3415 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3416
3417 test_33b() {
3418         rm -fr $DIR/$tdir
3419         test_mkdir $DIR/$tdir
3420         chown $RUNAS_ID $DIR/$tdir
3421         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3422 }
3423 run_test 33b "test open file with malformed flags (No panic)"
3424
3425 test_33c() {
3426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3427         remote_ost_nodsh && skip "remote OST with nodsh"
3428
3429         local ostnum
3430         local ostname
3431         local write_bytes
3432         local all_zeros
3433
3434         all_zeros=:
3435         rm -fr $DIR/$tdir
3436         test_mkdir $DIR/$tdir
3437         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3438
3439         sync
3440         for ostnum in $(seq $OSTCOUNT); do
3441                 # test-framework's OST numbering is one-based, while Lustre's
3442                 # is zero-based
3443                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3444                 # Parsing llobdstat's output sucks; we could grep the /proc
3445                 # path, but that's likely to not be as portable as using the
3446                 # llobdstat utility.  So we parse lctl output instead.
3447                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3448                         obdfilter/$ostname/stats |
3449                         awk '/^write_bytes/ {print $7}' )
3450                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3451                 if (( ${write_bytes:-0} > 0 ))
3452                 then
3453                         all_zeros=false
3454                         break;
3455                 fi
3456         done
3457
3458         $all_zeros || return 0
3459
3460         # Write four bytes
3461         echo foo > $DIR/$tdir/bar
3462         # Really write them
3463         sync
3464
3465         # Total up write_bytes after writing.  We'd better find non-zeros.
3466         for ostnum in $(seq $OSTCOUNT); do
3467                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3468                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3469                         obdfilter/$ostname/stats |
3470                         awk '/^write_bytes/ {print $7}' )
3471                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3472                 if (( ${write_bytes:-0} > 0 ))
3473                 then
3474                         all_zeros=false
3475                         break;
3476                 fi
3477         done
3478
3479         if $all_zeros
3480         then
3481                 for ostnum in $(seq $OSTCOUNT); do
3482                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3483                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3484                         do_facet ost$ostnum lctl get_param -n \
3485                                 obdfilter/$ostname/stats
3486                 done
3487                 error "OST not keeping write_bytes stats (b22312)"
3488         fi
3489 }
3490 run_test 33c "test llobdstat and write_bytes"
3491
3492 test_33d() {
3493         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3495
3496         local MDTIDX=1
3497         local remote_dir=$DIR/$tdir/remote_dir
3498
3499         test_mkdir $DIR/$tdir
3500         $LFS mkdir -i $MDTIDX $remote_dir ||
3501                 error "create remote directory failed"
3502
3503         touch $remote_dir/$tfile
3504         chmod 444 $remote_dir/$tfile
3505         chown $RUNAS_ID $remote_dir/$tfile
3506
3507         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3508
3509         chown $RUNAS_ID $remote_dir
3510         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3511                                         error "create" || true
3512         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3513                                     error "open RDWR" || true
3514         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3515 }
3516 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3517
3518 test_33e() {
3519         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3520
3521         mkdir $DIR/$tdir
3522
3523         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3524         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3525         mkdir $DIR/$tdir/local_dir
3526
3527         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3528         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3529         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3530
3531         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3532                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3533
3534         rmdir $DIR/$tdir/* || error "rmdir failed"
3535
3536         umask 777
3537         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3538         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3539         mkdir $DIR/$tdir/local_dir
3540
3541         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3542         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3543         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3544
3545         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3546                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3547
3548         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3549
3550         umask 000
3551         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3552         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3553         mkdir $DIR/$tdir/local_dir
3554
3555         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3556         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3557         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3558
3559         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3560                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3561 }
3562 run_test 33e "mkdir and striped directory should have same mode"
3563
3564 cleanup_33f() {
3565         trap 0
3566         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3567 }
3568
3569 test_33f() {
3570         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3571         remote_mds_nodsh && skip "remote MDS with nodsh"
3572
3573         mkdir $DIR/$tdir
3574         chmod go+rwx $DIR/$tdir
3575         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3576         trap cleanup_33f EXIT
3577
3578         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3579                 error "cannot create striped directory"
3580
3581         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3582                 error "cannot create files in striped directory"
3583
3584         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3585                 error "cannot remove files in striped directory"
3586
3587         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3588                 error "cannot remove striped directory"
3589
3590         cleanup_33f
3591 }
3592 run_test 33f "nonroot user can create, access, and remove a striped directory"
3593
3594 test_33g() {
3595         mkdir -p $DIR/$tdir/dir2
3596
3597         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3598         echo $err
3599         [[ $err =~ "exists" ]] || error "Not exists error"
3600 }
3601 run_test 33g "nonroot user create already existing root created file"
3602
3603 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3604 test_34a() {
3605         rm -f $DIR/f34
3606         $MCREATE $DIR/f34 || error "mcreate failed"
3607         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3608                 error "getstripe failed"
3609         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3610         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3611                 error "getstripe failed"
3612         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3613                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3614 }
3615 run_test 34a "truncate file that has not been opened ==========="
3616
3617 test_34b() {
3618         [ ! -f $DIR/f34 ] && test_34a
3619         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3620                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3621         $OPENFILE -f O_RDONLY $DIR/f34
3622         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3623                 error "getstripe failed"
3624         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3625                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3626 }
3627 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3628
3629 test_34c() {
3630         [ ! -f $DIR/f34 ] && test_34a
3631         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3632                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3633         $OPENFILE -f O_RDWR $DIR/f34
3634         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3635                 error "$LFS getstripe failed"
3636         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3637                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3638 }
3639 run_test 34c "O_RDWR opening file-with-size works =============="
3640
3641 test_34d() {
3642         [ ! -f $DIR/f34 ] && test_34a
3643         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3644                 error "dd failed"
3645         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3646                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3647         rm $DIR/f34
3648 }
3649 run_test 34d "write to sparse file ============================="
3650
3651 test_34e() {
3652         rm -f $DIR/f34e
3653         $MCREATE $DIR/f34e || error "mcreate failed"
3654         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3655         $CHECKSTAT -s 1000 $DIR/f34e ||
3656                 error "Size of $DIR/f34e not equal to 1000 bytes"
3657         $OPENFILE -f O_RDWR $DIR/f34e
3658         $CHECKSTAT -s 1000 $DIR/f34e ||
3659                 error "Size of $DIR/f34e not equal to 1000 bytes"
3660 }
3661 run_test 34e "create objects, some with size and some without =="
3662
3663 test_34f() { # bug 6242, 6243
3664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3665
3666         SIZE34F=48000
3667         rm -f $DIR/f34f
3668         $MCREATE $DIR/f34f || error "mcreate failed"
3669         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3670         dd if=$DIR/f34f of=$TMP/f34f
3671         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3672         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3673         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3674         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3675         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3676 }
3677 run_test 34f "read from a file with no objects until EOF ======="
3678
3679 test_34g() {
3680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3681
3682         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3683                 error "dd failed"
3684         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3685         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3686                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3687         cancel_lru_locks osc
3688         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3689                 error "wrong size after lock cancel"
3690
3691         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3692         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3693                 error "expanding truncate failed"
3694         cancel_lru_locks osc
3695         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3696                 error "wrong expanded size after lock cancel"
3697 }
3698 run_test 34g "truncate long file ==============================="
3699
3700 test_34h() {
3701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3702
3703         local gid=10
3704         local sz=1000
3705
3706         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3707         sync # Flush the cache so that multiop below does not block on cache
3708              # flush when getting the group lock
3709         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3710         MULTIPID=$!
3711
3712         # Since just timed wait is not good enough, let's do a sync write
3713         # that way we are sure enough time for a roundtrip + processing
3714         # passed + 2 seconds of extra margin.
3715         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3716         rm $DIR/${tfile}-1
3717         sleep 2
3718
3719         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3720                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3721                 kill -9 $MULTIPID
3722         fi
3723         wait $MULTIPID
3724         local nsz=`stat -c %s $DIR/$tfile`
3725         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3726 }
3727 run_test 34h "ftruncate file under grouplock should not block"
3728
3729 test_35a() {
3730         cp /bin/sh $DIR/f35a
3731         chmod 444 $DIR/f35a
3732         chown $RUNAS_ID $DIR/f35a
3733         $RUNAS $DIR/f35a && error || true
3734         rm $DIR/f35a
3735 }
3736 run_test 35a "exec file with mode 444 (should return and not leak)"
3737
3738 test_36a() {
3739         rm -f $DIR/f36
3740         utime $DIR/f36 || error "utime failed for MDS"
3741 }
3742 run_test 36a "MDS utime check (mknod, utime)"
3743
3744 test_36b() {
3745         echo "" > $DIR/f36
3746         utime $DIR/f36 || error "utime failed for OST"
3747 }
3748 run_test 36b "OST utime check (open, utime)"
3749
3750 test_36c() {
3751         rm -f $DIR/d36/f36
3752         test_mkdir $DIR/d36
3753         chown $RUNAS_ID $DIR/d36
3754         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3755 }
3756 run_test 36c "non-root MDS utime check (mknod, utime)"
3757
3758 test_36d() {
3759         [ ! -d $DIR/d36 ] && test_36c
3760         echo "" > $DIR/d36/f36
3761         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3762 }
3763 run_test 36d "non-root OST utime check (open, utime)"
3764
3765 test_36e() {
3766         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3767
3768         test_mkdir $DIR/$tdir
3769         touch $DIR/$tdir/$tfile
3770         $RUNAS utime $DIR/$tdir/$tfile &&
3771                 error "utime worked, expected failure" || true
3772 }
3773 run_test 36e "utime on non-owned file (should return error)"
3774
3775 subr_36fh() {
3776         local fl="$1"
3777         local LANG_SAVE=$LANG
3778         local LC_LANG_SAVE=$LC_LANG
3779         export LANG=C LC_LANG=C # for date language
3780
3781         DATESTR="Dec 20  2000"
3782         test_mkdir $DIR/$tdir
3783         lctl set_param fail_loc=$fl
3784         date; date +%s
3785         cp /etc/hosts $DIR/$tdir/$tfile
3786         sync & # write RPC generated with "current" inode timestamp, but delayed
3787         sleep 1
3788         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3789         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3790         cancel_lru_locks $OSC
3791         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3792         date; date +%s
3793         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3794                 echo "BEFORE: $LS_BEFORE" && \
3795                 echo "AFTER : $LS_AFTER" && \
3796                 echo "WANT  : $DATESTR" && \
3797                 error "$DIR/$tdir/$tfile timestamps changed" || true
3798
3799         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3800 }
3801
3802 test_36f() {
3803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3804
3805         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3806         subr_36fh "0x80000214"
3807 }
3808 run_test 36f "utime on file racing with OST BRW write =========="
3809
3810 test_36g() {
3811         remote_ost_nodsh && skip "remote OST with nodsh"
3812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3813         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
3814                 skip "Need MDS version at least 2.12.51"
3815
3816         local fmd_max_age
3817         local fmd
3818         local facet="ost1"
3819         local tgt="obdfilter"
3820
3821         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
3822
3823         test_mkdir $DIR/$tdir
3824         fmd_max_age=$(do_facet $facet \
3825                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
3826                 head -n 1")
3827
3828         echo "FMD max age: ${fmd_max_age}s"
3829         touch $DIR/$tdir/$tfile
3830         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3831                 gawk '{cnt=cnt+$1}  END{print cnt}')
3832         echo "FMD before: $fmd"
3833         [[ $fmd == 0 ]] &&
3834                 error "FMD wasn't create by touch"
3835         sleep $((fmd_max_age + 12))
3836         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3837                 gawk '{cnt=cnt+$1}  END{print cnt}')
3838         echo "FMD after: $fmd"
3839         [[ $fmd == 0 ]] ||
3840                 error "FMD wasn't expired by ping"
3841 }
3842 run_test 36g "FMD cache expiry ====================="
3843
3844 test_36h() {
3845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3846
3847         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
3848         subr_36fh "0x80000227"
3849 }
3850 run_test 36h "utime on file racing with OST BRW write =========="
3851
3852 test_36i() {
3853         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3854
3855         test_mkdir $DIR/$tdir
3856         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
3857
3858         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
3859         local new_mtime=$((mtime + 200))
3860
3861         #change Modify time of striped dir
3862         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
3863                         error "change mtime failed"
3864
3865         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
3866
3867         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
3868 }
3869 run_test 36i "change mtime on striped directory"
3870
3871 # test_37 - duplicate with tests 32q 32r
3872
3873 test_38() {
3874         local file=$DIR/$tfile
3875         touch $file
3876         openfile -f O_DIRECTORY $file
3877         local RC=$?
3878         local ENOTDIR=20
3879         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
3880         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
3881 }
3882 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
3883
3884 test_39a() { # was test_39
3885         touch $DIR/$tfile
3886         touch $DIR/${tfile}2
3887 #       ls -l  $DIR/$tfile $DIR/${tfile}2
3888 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
3889 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
3890         sleep 2
3891         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
3892         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
3893                 echo "mtime"
3894                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
3895                 echo "atime"
3896                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
3897                 echo "ctime"
3898                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
3899                 error "O_TRUNC didn't change timestamps"
3900         fi
3901 }
3902 run_test 39a "mtime changed on create"
3903
3904 test_39b() {
3905         test_mkdir -c1 $DIR/$tdir
3906         cp -p /etc/passwd $DIR/$tdir/fopen
3907         cp -p /etc/passwd $DIR/$tdir/flink
3908         cp -p /etc/passwd $DIR/$tdir/funlink
3909         cp -p /etc/passwd $DIR/$tdir/frename
3910         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
3911
3912         sleep 1
3913         echo "aaaaaa" >> $DIR/$tdir/fopen
3914         echo "aaaaaa" >> $DIR/$tdir/flink
3915         echo "aaaaaa" >> $DIR/$tdir/funlink
3916         echo "aaaaaa" >> $DIR/$tdir/frename
3917
3918         local open_new=`stat -c %Y $DIR/$tdir/fopen`
3919         local link_new=`stat -c %Y $DIR/$tdir/flink`
3920         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
3921         local rename_new=`stat -c %Y $DIR/$tdir/frename`
3922
3923         cat $DIR/$tdir/fopen > /dev/null
3924         ln $DIR/$tdir/flink $DIR/$tdir/flink2
3925         rm -f $DIR/$tdir/funlink2
3926         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
3927
3928         for (( i=0; i < 2; i++ )) ; do
3929                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
3930                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
3931                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
3932                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
3933
3934                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
3935                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
3936                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
3937                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
3938
3939                 cancel_lru_locks $OSC
3940                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3941         done
3942 }
3943 run_test 39b "mtime change on open, link, unlink, rename  ======"
3944
3945 # this should be set to past
3946 TEST_39_MTIME=`date -d "1 year ago" +%s`
3947
3948 # bug 11063
3949 test_39c() {
3950         touch $DIR1/$tfile
3951         sleep 2
3952         local mtime0=`stat -c %Y $DIR1/$tfile`
3953
3954         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3955         local mtime1=`stat -c %Y $DIR1/$tfile`
3956         [ "$mtime1" = $TEST_39_MTIME ] || \
3957                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
3958
3959         local d1=`date +%s`
3960         echo hello >> $DIR1/$tfile
3961         local d2=`date +%s`
3962         local mtime2=`stat -c %Y $DIR1/$tfile`
3963         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
3964                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
3965
3966         mv $DIR1/$tfile $DIR1/$tfile-1
3967
3968         for (( i=0; i < 2; i++ )) ; do
3969                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
3970                 [ "$mtime2" = "$mtime3" ] || \
3971                         error "mtime ($mtime2) changed (to $mtime3) on rename"
3972
3973                 cancel_lru_locks $OSC
3974                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3975         done
3976 }
3977 run_test 39c "mtime change on rename ==========================="
3978
3979 # bug 21114
3980 test_39d() {
3981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3982
3983         touch $DIR1/$tfile
3984         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3985
3986         for (( i=0; i < 2; i++ )) ; do
3987                 local mtime=`stat -c %Y $DIR1/$tfile`
3988                 [ $mtime = $TEST_39_MTIME ] || \
3989                         error "mtime($mtime) is not set to $TEST_39_MTIME"
3990
3991                 cancel_lru_locks $OSC
3992                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3993         done
3994 }
3995 run_test 39d "create, utime, stat =============================="
3996
3997 # bug 21114
3998 test_39e() {
3999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4000
4001         touch $DIR1/$tfile
4002         local mtime1=`stat -c %Y $DIR1/$tfile`
4003
4004         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4005
4006         for (( i=0; i < 2; i++ )) ; do
4007                 local mtime2=`stat -c %Y $DIR1/$tfile`
4008                 [ $mtime2 = $TEST_39_MTIME ] || \
4009                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4010
4011                 cancel_lru_locks $OSC
4012                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4013         done
4014 }
4015 run_test 39e "create, stat, utime, stat ========================"
4016
4017 # bug 21114
4018 test_39f() {
4019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4020
4021         touch $DIR1/$tfile
4022         mtime1=`stat -c %Y $DIR1/$tfile`
4023
4024         sleep 2
4025         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4026
4027         for (( i=0; i < 2; i++ )) ; do
4028                 local mtime2=`stat -c %Y $DIR1/$tfile`
4029                 [ $mtime2 = $TEST_39_MTIME ] || \
4030                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4031
4032                 cancel_lru_locks $OSC
4033                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4034         done
4035 }
4036 run_test 39f "create, stat, sleep, utime, stat ================="
4037
4038 # bug 11063
4039 test_39g() {
4040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4041
4042         echo hello >> $DIR1/$tfile
4043         local mtime1=`stat -c %Y $DIR1/$tfile`
4044
4045         sleep 2
4046         chmod o+r $DIR1/$tfile
4047
4048         for (( i=0; i < 2; i++ )) ; do
4049                 local mtime2=`stat -c %Y $DIR1/$tfile`
4050                 [ "$mtime1" = "$mtime2" ] || \
4051                         error "lost mtime: $mtime2, should be $mtime1"
4052
4053                 cancel_lru_locks $OSC
4054                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4055         done
4056 }
4057 run_test 39g "write, chmod, stat ==============================="
4058
4059 # bug 11063
4060 test_39h() {
4061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4062
4063         touch $DIR1/$tfile
4064         sleep 1
4065
4066         local d1=`date`
4067         echo hello >> $DIR1/$tfile
4068         local mtime1=`stat -c %Y $DIR1/$tfile`
4069
4070         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4071         local d2=`date`
4072         if [ "$d1" != "$d2" ]; then
4073                 echo "write and touch not within one second"
4074         else
4075                 for (( i=0; i < 2; i++ )) ; do
4076                         local mtime2=`stat -c %Y $DIR1/$tfile`
4077                         [ "$mtime2" = $TEST_39_MTIME ] || \
4078                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4079
4080                         cancel_lru_locks $OSC
4081                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4082                 done
4083         fi
4084 }
4085 run_test 39h "write, utime within one second, stat ============="
4086
4087 test_39i() {
4088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4089
4090         touch $DIR1/$tfile
4091         sleep 1
4092
4093         echo hello >> $DIR1/$tfile
4094         local mtime1=`stat -c %Y $DIR1/$tfile`
4095
4096         mv $DIR1/$tfile $DIR1/$tfile-1
4097
4098         for (( i=0; i < 2; i++ )) ; do
4099                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4100
4101                 [ "$mtime1" = "$mtime2" ] || \
4102                         error "lost mtime: $mtime2, should be $mtime1"
4103
4104                 cancel_lru_locks $OSC
4105                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4106         done
4107 }
4108 run_test 39i "write, rename, stat =============================="
4109
4110 test_39j() {
4111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4112
4113         start_full_debug_logging
4114         touch $DIR1/$tfile
4115         sleep 1
4116
4117         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4118         lctl set_param fail_loc=0x80000412
4119         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4120                 error "multiop failed"
4121         local multipid=$!
4122         local mtime1=`stat -c %Y $DIR1/$tfile`
4123
4124         mv $DIR1/$tfile $DIR1/$tfile-1
4125
4126         kill -USR1 $multipid
4127         wait $multipid || error "multiop close failed"
4128
4129         for (( i=0; i < 2; i++ )) ; do
4130                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4131                 [ "$mtime1" = "$mtime2" ] ||
4132                         error "mtime is lost on close: $mtime2, " \
4133                               "should be $mtime1"
4134
4135                 cancel_lru_locks $OSC
4136                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4137         done
4138         lctl set_param fail_loc=0
4139         stop_full_debug_logging
4140 }
4141 run_test 39j "write, rename, close, stat ======================="
4142
4143 test_39k() {
4144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4145
4146         touch $DIR1/$tfile
4147         sleep 1
4148
4149         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4150         local multipid=$!
4151         local mtime1=`stat -c %Y $DIR1/$tfile`
4152
4153         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4154
4155         kill -USR1 $multipid
4156         wait $multipid || error "multiop close failed"
4157
4158         for (( i=0; i < 2; i++ )) ; do
4159                 local mtime2=`stat -c %Y $DIR1/$tfile`
4160
4161                 [ "$mtime2" = $TEST_39_MTIME ] || \
4162                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4163
4164                 cancel_lru_locks osc
4165                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4166         done
4167 }
4168 run_test 39k "write, utime, close, stat ========================"
4169
4170 # this should be set to future
4171 TEST_39_ATIME=`date -d "1 year" +%s`
4172
4173 test_39l() {
4174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4175         remote_mds_nodsh && skip "remote MDS with nodsh"
4176
4177         local atime_diff=$(do_facet $SINGLEMDS \
4178                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4179         rm -rf $DIR/$tdir
4180         mkdir -p $DIR/$tdir
4181
4182         # test setting directory atime to future
4183         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4184         local atime=$(stat -c %X $DIR/$tdir)
4185         [ "$atime" = $TEST_39_ATIME ] ||
4186                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4187
4188         # test setting directory atime from future to now
4189         local now=$(date +%s)
4190         touch -a -d @$now $DIR/$tdir
4191
4192         atime=$(stat -c %X $DIR/$tdir)
4193         [ "$atime" -eq "$now"  ] ||
4194                 error "atime is not updated from future: $atime, $now"
4195
4196         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4197         sleep 3
4198
4199         # test setting directory atime when now > dir atime + atime_diff
4200         local d1=$(date +%s)
4201         ls $DIR/$tdir
4202         local d2=$(date +%s)
4203         cancel_lru_locks mdc
4204         atime=$(stat -c %X $DIR/$tdir)
4205         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4206                 error "atime is not updated  : $atime, should be $d2"
4207
4208         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4209         sleep 3
4210
4211         # test not setting directory atime when now < dir atime + atime_diff
4212         ls $DIR/$tdir
4213         cancel_lru_locks mdc
4214         atime=$(stat -c %X $DIR/$tdir)
4215         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4216                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4217
4218         do_facet $SINGLEMDS \
4219                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4220 }
4221 run_test 39l "directory atime update ==========================="
4222
4223 test_39m() {
4224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4225
4226         touch $DIR1/$tfile
4227         sleep 2
4228         local far_past_mtime=$(date -d "May 29 1953" +%s)
4229         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4230
4231         touch -m -d @$far_past_mtime $DIR1/$tfile
4232         touch -a -d @$far_past_atime $DIR1/$tfile
4233
4234         for (( i=0; i < 2; i++ )) ; do
4235                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4236                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4237                         error "atime or mtime set incorrectly"
4238
4239                 cancel_lru_locks $OSC
4240                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4241         done
4242 }
4243 run_test 39m "test atime and mtime before 1970"
4244
4245 test_39n() { # LU-3832
4246         remote_mds_nodsh && skip "remote MDS with nodsh"
4247
4248         local atime_diff=$(do_facet $SINGLEMDS \
4249                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4250         local atime0
4251         local atime1
4252         local atime2
4253
4254         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4255
4256         rm -rf $DIR/$tfile
4257         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4258         atime0=$(stat -c %X $DIR/$tfile)
4259
4260         sleep 5
4261         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4262         atime1=$(stat -c %X $DIR/$tfile)
4263
4264         sleep 5
4265         cancel_lru_locks mdc
4266         cancel_lru_locks osc
4267         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4268         atime2=$(stat -c %X $DIR/$tfile)
4269
4270         do_facet $SINGLEMDS \
4271                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4272
4273         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4274         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4275 }
4276 run_test 39n "check that O_NOATIME is honored"
4277
4278 test_39o() {
4279         TESTDIR=$DIR/$tdir/$tfile
4280         [ -e $TESTDIR ] && rm -rf $TESTDIR
4281         mkdir -p $TESTDIR
4282         cd $TESTDIR
4283         links1=2
4284         ls
4285         mkdir a b
4286         ls
4287         links2=$(stat -c %h .)
4288         [ $(($links1 + 2)) != $links2 ] &&
4289                 error "wrong links count $(($links1 + 2)) != $links2"
4290         rmdir b
4291         links3=$(stat -c %h .)
4292         [ $(($links1 + 1)) != $links3 ] &&
4293                 error "wrong links count $links1 != $links3"
4294         return 0
4295 }
4296 run_test 39o "directory cached attributes updated after create"
4297
4298 test_39p() {
4299         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4300
4301         local MDTIDX=1
4302         TESTDIR=$DIR/$tdir/$tdir
4303         [ -e $TESTDIR ] && rm -rf $TESTDIR
4304         test_mkdir -p $TESTDIR
4305         cd $TESTDIR
4306         links1=2
4307         ls
4308         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4309         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4310         ls
4311         links2=$(stat -c %h .)
4312         [ $(($links1 + 2)) != $links2 ] &&
4313                 error "wrong links count $(($links1 + 2)) != $links2"
4314         rmdir remote_dir2
4315         links3=$(stat -c %h .)
4316         [ $(($links1 + 1)) != $links3 ] &&
4317                 error "wrong links count $links1 != $links3"
4318         return 0
4319 }
4320 run_test 39p "remote directory cached attributes updated after create ========"
4321
4322
4323 test_39q() { # LU-8041
4324         local testdir=$DIR/$tdir
4325         mkdir -p $testdir
4326         multiop_bg_pause $testdir D_c || error "multiop failed"
4327         local multipid=$!
4328         cancel_lru_locks mdc
4329         kill -USR1 $multipid
4330         local atime=$(stat -c %X $testdir)
4331         [ "$atime" -ne 0 ] || error "atime is zero"
4332 }
4333 run_test 39q "close won't zero out atime"
4334
4335 test_40() {
4336         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4337         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4338                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4339         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4340                 error "$tfile is not 4096 bytes in size"
4341 }
4342 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4343
4344 test_41() {
4345         # bug 1553
4346         small_write $DIR/f41 18
4347 }
4348 run_test 41 "test small file write + fstat ====================="
4349
4350 count_ost_writes() {
4351         lctl get_param -n ${OSC}.*.stats |
4352                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4353                         END { printf("%0.0f", writes) }'
4354 }
4355
4356 # decent default
4357 WRITEBACK_SAVE=500
4358 DIRTY_RATIO_SAVE=40
4359 MAX_DIRTY_RATIO=50
4360 BG_DIRTY_RATIO_SAVE=10
4361 MAX_BG_DIRTY_RATIO=25
4362
4363 start_writeback() {
4364         trap 0
4365         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4366         # dirty_ratio, dirty_background_ratio
4367         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4368                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4369                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4370                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4371         else
4372                 # if file not here, we are a 2.4 kernel
4373                 kill -CONT `pidof kupdated`
4374         fi
4375 }
4376
4377 stop_writeback() {
4378         # setup the trap first, so someone cannot exit the test at the
4379         # exact wrong time and mess up a machine
4380         trap start_writeback EXIT
4381         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4382         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4383                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4384                 sysctl -w vm.dirty_writeback_centisecs=0
4385                 sysctl -w vm.dirty_writeback_centisecs=0
4386                 # save and increase /proc/sys/vm/dirty_ratio
4387                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4388                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4389                 # save and increase /proc/sys/vm/dirty_background_ratio
4390                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4391                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4392         else
4393                 # if file not here, we are a 2.4 kernel
4394                 kill -STOP `pidof kupdated`
4395         fi
4396 }
4397
4398 # ensure that all stripes have some grant before we test client-side cache
4399 setup_test42() {
4400         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4401                 dd if=/dev/zero of=$i bs=4k count=1
4402                 rm $i
4403         done
4404 }
4405
4406 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4407 # file truncation, and file removal.
4408 test_42a() {
4409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4410
4411         setup_test42
4412         cancel_lru_locks $OSC
4413         stop_writeback
4414         sync; sleep 1; sync # just to be safe
4415         BEFOREWRITES=`count_ost_writes`
4416         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4417         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4418         AFTERWRITES=`count_ost_writes`
4419         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4420                 error "$BEFOREWRITES < $AFTERWRITES"
4421         start_writeback
4422 }
4423 run_test 42a "ensure that we don't flush on close"
4424
4425 test_42b() {
4426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4427
4428         setup_test42
4429         cancel_lru_locks $OSC
4430         stop_writeback
4431         sync
4432         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4433         BEFOREWRITES=$(count_ost_writes)
4434         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4435         AFTERWRITES=$(count_ost_writes)
4436         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4437                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4438         fi
4439         BEFOREWRITES=$(count_ost_writes)
4440         sync || error "sync: $?"
4441         AFTERWRITES=$(count_ost_writes)
4442         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4443                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4444         fi
4445         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4446         start_writeback
4447         return 0
4448 }
4449 run_test 42b "test destroy of file with cached dirty data ======"
4450
4451 # if these tests just want to test the effect of truncation,
4452 # they have to be very careful.  consider:
4453 # - the first open gets a {0,EOF}PR lock
4454 # - the first write conflicts and gets a {0, count-1}PW
4455 # - the rest of the writes are under {count,EOF}PW
4456 # - the open for truncate tries to match a {0,EOF}PR
4457 #   for the filesize and cancels the PWs.
4458 # any number of fixes (don't get {0,EOF} on open, match
4459 # composite locks, do smarter file size management) fix
4460 # this, but for now we want these tests to verify that
4461 # the cancellation with truncate intent works, so we
4462 # start the file with a full-file pw lock to match against
4463 # until the truncate.
4464 trunc_test() {
4465         test=$1
4466         file=$DIR/$test
4467         offset=$2
4468         cancel_lru_locks $OSC
4469         stop_writeback
4470         # prime the file with 0,EOF PW to match
4471         touch $file
4472         $TRUNCATE $file 0
4473         sync; sync
4474         # now the real test..
4475         dd if=/dev/zero of=$file bs=1024 count=100
4476         BEFOREWRITES=`count_ost_writes`
4477         $TRUNCATE $file $offset
4478         cancel_lru_locks $OSC
4479         AFTERWRITES=`count_ost_writes`
4480         start_writeback
4481 }
4482
4483 test_42c() {
4484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4485
4486         trunc_test 42c 1024
4487         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4488                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4489         rm $file
4490 }
4491 run_test 42c "test partial truncate of file with cached dirty data"
4492
4493 test_42d() {
4494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4495
4496         trunc_test 42d 0
4497         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4498                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4499         rm $file
4500 }
4501 run_test 42d "test complete truncate of file with cached dirty data"
4502
4503 test_42e() { # bug22074
4504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4505
4506         local TDIR=$DIR/${tdir}e
4507         local pages=16 # hardcoded 16 pages, don't change it.
4508         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4509         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4510         local max_dirty_mb
4511         local warmup_files
4512
4513         test_mkdir $DIR/${tdir}e
4514         $LFS setstripe -c 1 $TDIR
4515         createmany -o $TDIR/f $files
4516
4517         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4518
4519         # we assume that with $OSTCOUNT files, at least one of them will
4520         # be allocated on OST0.
4521         warmup_files=$((OSTCOUNT * max_dirty_mb))
4522         createmany -o $TDIR/w $warmup_files
4523
4524         # write a large amount of data into one file and sync, to get good
4525         # avail_grant number from OST.
4526         for ((i=0; i<$warmup_files; i++)); do
4527                 idx=$($LFS getstripe -i $TDIR/w$i)
4528                 [ $idx -ne 0 ] && continue
4529                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4530                 break
4531         done
4532         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4533         sync
4534         $LCTL get_param $proc_osc0/cur_dirty_bytes
4535         $LCTL get_param $proc_osc0/cur_grant_bytes
4536
4537         # create as much dirty pages as we can while not to trigger the actual
4538         # RPCs directly. but depends on the env, VFS may trigger flush during this
4539         # period, hopefully we are good.
4540         for ((i=0; i<$warmup_files; i++)); do
4541                 idx=$($LFS getstripe -i $TDIR/w$i)
4542                 [ $idx -ne 0 ] && continue
4543                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4544         done
4545         $LCTL get_param $proc_osc0/cur_dirty_bytes
4546         $LCTL get_param $proc_osc0/cur_grant_bytes
4547
4548         # perform the real test
4549         $LCTL set_param $proc_osc0/rpc_stats 0
4550         for ((;i<$files; i++)); do
4551                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4552                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4553         done
4554         sync
4555         $LCTL get_param $proc_osc0/rpc_stats
4556
4557         local percent=0
4558         local have_ppr=false
4559         $LCTL get_param $proc_osc0/rpc_stats |
4560                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4561                         # skip lines until we are at the RPC histogram data
4562                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4563                         $have_ppr || continue
4564
4565                         # we only want the percent stat for < 16 pages
4566                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4567
4568                         percent=$((percent + WPCT))
4569                         if [[ $percent -gt 15 ]]; then
4570                                 error "less than 16-pages write RPCs" \
4571                                       "$percent% > 15%"
4572                                 break
4573                         fi
4574                 done
4575         rm -rf $TDIR
4576 }
4577 run_test 42e "verify sub-RPC writes are not done synchronously"
4578
4579 test_43A() { # was test_43
4580         test_mkdir $DIR/$tdir
4581         cp -p /bin/ls $DIR/$tdir/$tfile
4582         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4583         pid=$!
4584         # give multiop a chance to open
4585         sleep 1
4586
4587         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4588         kill -USR1 $pid
4589 }
4590 run_test 43A "execution of file opened for write should return -ETXTBSY"
4591
4592 test_43a() {
4593         test_mkdir $DIR/$tdir
4594         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4595         $DIR/$tdir/sleep 60 &
4596         SLEEP_PID=$!
4597         # Make sure exec of $tdir/sleep wins race with truncate
4598         sleep 1
4599         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4600         kill $SLEEP_PID
4601 }
4602 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4603
4604 test_43b() {
4605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4606
4607         test_mkdir $DIR/$tdir
4608         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4609         $DIR/$tdir/sleep 60 &
4610         SLEEP_PID=$!
4611         # Make sure exec of $tdir/sleep wins race with truncate
4612         sleep 1
4613         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4614         kill $SLEEP_PID
4615 }
4616 run_test 43b "truncate of file being executed should return -ETXTBSY"
4617
4618 test_43c() {
4619         local testdir="$DIR/$tdir"
4620         test_mkdir $testdir
4621         cp $SHELL $testdir/
4622         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4623                 ( cd $testdir && md5sum -c )
4624 }
4625 run_test 43c "md5sum of copy into lustre"
4626
4627 test_44A() { # was test_44
4628         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4629
4630         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4631         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4632 }
4633 run_test 44A "zero length read from a sparse stripe"
4634
4635 test_44a() {
4636         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4637                 awk '{ print $2 }')
4638         [ -z "$nstripe" ] && skip "can't get stripe info"
4639         [[ $nstripe -gt $OSTCOUNT ]] &&
4640                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4641
4642         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4643                 awk '{ print $2 }')
4644         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4645                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4646                         awk '{ print $2 }')
4647         fi
4648
4649         OFFSETS="0 $((stride/2)) $((stride-1))"
4650         for offset in $OFFSETS; do
4651                 for i in $(seq 0 $((nstripe-1))); do
4652                         local GLOBALOFFSETS=""
4653                         # size in Bytes
4654                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4655                         local myfn=$DIR/d44a-$size
4656                         echo "--------writing $myfn at $size"
4657                         ll_sparseness_write $myfn $size ||
4658                                 error "ll_sparseness_write"
4659                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4660                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4661                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4662
4663                         for j in $(seq 0 $((nstripe-1))); do
4664                                 # size in Bytes
4665                                 size=$((((j + $nstripe )*$stride + $offset)))
4666                                 ll_sparseness_write $myfn $size ||
4667                                         error "ll_sparseness_write"
4668                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4669                         done
4670                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4671                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4672                         rm -f $myfn
4673                 done
4674         done
4675 }
4676 run_test 44a "test sparse pwrite ==============================="
4677
4678 dirty_osc_total() {
4679         tot=0
4680         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4681                 tot=$(($tot + $d))
4682         done
4683         echo $tot
4684 }
4685 do_dirty_record() {
4686         before=`dirty_osc_total`
4687         echo executing "\"$*\""
4688         eval $*
4689         after=`dirty_osc_total`
4690         echo before $before, after $after
4691 }
4692 test_45() {
4693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4694
4695         f="$DIR/f45"
4696         # Obtain grants from OST if it supports it
4697         echo blah > ${f}_grant
4698         stop_writeback
4699         sync
4700         do_dirty_record "echo blah > $f"
4701         [[ $before -eq $after ]] && error "write wasn't cached"
4702         do_dirty_record "> $f"
4703         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4704         do_dirty_record "echo blah > $f"
4705         [[ $before -eq $after ]] && error "write wasn't cached"
4706         do_dirty_record "sync"
4707         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4708         do_dirty_record "echo blah > $f"
4709         [[ $before -eq $after ]] && error "write wasn't cached"
4710         do_dirty_record "cancel_lru_locks osc"
4711         [[ $before -gt $after ]] ||
4712                 error "lock cancellation didn't lower dirty count"
4713         start_writeback
4714 }
4715 run_test 45 "osc io page accounting ============================"
4716
4717 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4718 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4719 # objects offset and an assert hit when an rpc was built with 1023's mapped
4720 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4721 test_46() {
4722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4723
4724         f="$DIR/f46"
4725         stop_writeback
4726         sync
4727         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4728         sync
4729         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4730         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4731         sync
4732         start_writeback
4733 }
4734 run_test 46 "dirtying a previously written page ================"
4735
4736 # test_47 is removed "Device nodes check" is moved to test_28
4737
4738 test_48a() { # bug 2399
4739         [ "$mds1_FSTYPE" = "zfs" ] &&
4740         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4741                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4742
4743         test_mkdir $DIR/$tdir
4744         cd $DIR/$tdir
4745         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4746         test_mkdir $DIR/$tdir
4747         touch foo || error "'touch foo' failed after recreating cwd"
4748         test_mkdir bar
4749         touch .foo || error "'touch .foo' failed after recreating cwd"
4750         test_mkdir .bar
4751         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4752         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4753         cd . || error "'cd .' failed after recreating cwd"
4754         mkdir . && error "'mkdir .' worked after recreating cwd"
4755         rmdir . && error "'rmdir .' worked after recreating cwd"
4756         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4757         cd .. || error "'cd ..' failed after recreating cwd"
4758 }
4759 run_test 48a "Access renamed working dir (should return errors)="
4760
4761 test_48b() { # bug 2399
4762         rm -rf $DIR/$tdir
4763         test_mkdir $DIR/$tdir
4764         cd $DIR/$tdir
4765         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4766         touch foo && error "'touch foo' worked after removing cwd"
4767         mkdir foo && error "'mkdir foo' worked after removing cwd"
4768         touch .foo && error "'touch .foo' worked after removing cwd"
4769         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
4770         ls . > /dev/null && error "'ls .' worked after removing cwd"
4771         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4772         mkdir . && error "'mkdir .' worked after removing cwd"
4773         rmdir . && error "'rmdir .' worked after removing cwd"
4774         ln -s . foo && error "'ln -s .' worked after removing cwd"
4775         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
4776 }
4777 run_test 48b "Access removed working dir (should return errors)="
4778
4779 test_48c() { # bug 2350
4780         #lctl set_param debug=-1
4781         #set -vx
4782         rm -rf $DIR/$tdir
4783         test_mkdir -p $DIR/$tdir/dir
4784         cd $DIR/$tdir/dir
4785         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4786         $TRACE touch foo && error "touch foo worked after removing cwd"
4787         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
4788         touch .foo && error "touch .foo worked after removing cwd"
4789         mkdir .foo && error "mkdir .foo worked after removing cwd"
4790         $TRACE ls . && error "'ls .' worked after removing cwd"
4791         $TRACE ls .. || error "'ls ..' failed after removing cwd"
4792         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
4793         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
4794         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
4795         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
4796 }
4797 run_test 48c "Access removed working subdir (should return errors)"
4798
4799 test_48d() { # bug 2350
4800         #lctl set_param debug=-1
4801         #set -vx
4802         rm -rf $DIR/$tdir
4803         test_mkdir -p $DIR/$tdir/dir
4804         cd $DIR/$tdir/dir
4805         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4806         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4807         $TRACE touch foo && error "'touch foo' worked after removing parent"
4808         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
4809         touch .foo && error "'touch .foo' worked after removing parent"
4810         mkdir .foo && error "mkdir .foo worked after removing parent"
4811         $TRACE ls . && error "'ls .' worked after removing parent"
4812         $TRACE ls .. && error "'ls ..' worked after removing parent"
4813         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
4814         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
4815         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
4816         true
4817 }
4818 run_test 48d "Access removed parent subdir (should return errors)"
4819
4820 test_48e() { # bug 4134
4821         #lctl set_param debug=-1
4822         #set -vx
4823         rm -rf $DIR/$tdir
4824         test_mkdir -p $DIR/$tdir/dir
4825         cd $DIR/$tdir/dir
4826         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4827         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4828         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
4829         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
4830         # On a buggy kernel addition of "touch foo" after cd .. will
4831         # produce kernel oops in lookup_hash_it
4832         touch ../foo && error "'cd ..' worked after recreate parent"
4833         cd $DIR
4834         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
4835 }
4836 run_test 48e "Access to recreated parent subdir (should return errors)"
4837
4838 test_49() { # LU-1030
4839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4840         remote_ost_nodsh && skip "remote OST with nodsh"
4841
4842         # get ost1 size - lustre-OST0000
4843         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
4844                 awk '{ print $4 }')
4845         # write 800M at maximum
4846         [[ $ost1_size -lt 2 ]] && ost1_size=2
4847         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
4848
4849         $LFS setstripe -c 1 -i 0 $DIR/$tfile
4850         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
4851         local dd_pid=$!
4852
4853         # change max_pages_per_rpc while writing the file
4854         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
4855         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
4856         # loop until dd process exits
4857         while ps ax -opid | grep -wq $dd_pid; do
4858                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
4859                 sleep $((RANDOM % 5 + 1))
4860         done
4861         # restore original max_pages_per_rpc
4862         $LCTL set_param $osc1_mppc=$orig_mppc
4863         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
4864 }
4865 run_test 49 "Change max_pages_per_rpc won't break osc extent"
4866
4867 test_50() {
4868         # bug 1485
4869         test_mkdir $DIR/$tdir
4870         cd $DIR/$tdir
4871         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
4872 }
4873 run_test 50 "special situations: /proc symlinks  ==============="
4874
4875 test_51a() {    # was test_51
4876         # bug 1516 - create an empty entry right after ".." then split dir
4877         test_mkdir -c1 $DIR/$tdir
4878         touch $DIR/$tdir/foo
4879         $MCREATE $DIR/$tdir/bar
4880         rm $DIR/$tdir/foo
4881         createmany -m $DIR/$tdir/longfile 201
4882         FNUM=202
4883         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
4884                 $MCREATE $DIR/$tdir/longfile$FNUM
4885                 FNUM=$(($FNUM + 1))
4886                 echo -n "+"
4887         done
4888         echo
4889         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
4890 }
4891 run_test 51a "special situations: split htree with empty entry =="
4892
4893 cleanup_print_lfs_df () {
4894         trap 0
4895         $LFS df
4896         $LFS df -i
4897 }
4898
4899 test_51b() {
4900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4901
4902         local dir=$DIR/$tdir
4903         local nrdirs=$((65536 + 100))
4904
4905         # cleanup the directory
4906         rm -fr $dir
4907
4908         test_mkdir -c1 $dir
4909
4910         $LFS df
4911         $LFS df -i
4912         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
4913         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
4914         [[ $numfree -lt $nrdirs ]] &&
4915                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
4916
4917         # need to check free space for the directories as well
4918         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
4919         numfree=$(( blkfree / $(fs_inode_ksize) ))
4920         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
4921
4922         trap cleanup_print_lfs_df EXIT
4923
4924         # create files
4925         createmany -d $dir/d $nrdirs || {
4926                 unlinkmany $dir/d $nrdirs
4927                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
4928         }
4929
4930         # really created :
4931         nrdirs=$(ls -U $dir | wc -l)
4932
4933         # unlink all but 100 subdirectories, then check it still works
4934         local left=100
4935         local delete=$((nrdirs - left))
4936
4937         $LFS df
4938         $LFS df -i
4939
4940         # for ldiskfs the nlink count should be 1, but this is OSD specific
4941         # and so this is listed for informational purposes only
4942         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
4943         unlinkmany -d $dir/d $delete ||
4944                 error "unlink of first $delete subdirs failed"
4945
4946         echo "nlink between: $(stat -c %h $dir)"
4947         local found=$(ls -U $dir | wc -l)
4948         [ $found -ne $left ] &&
4949                 error "can't find subdirs: found only $found, expected $left"
4950
4951         unlinkmany -d $dir/d $delete $left ||
4952                 error "unlink of second $left subdirs failed"
4953         # regardless of whether the backing filesystem tracks nlink accurately
4954         # or not, the nlink count shouldn't be more than "." and ".." here
4955         local after=$(stat -c %h $dir)
4956         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
4957                 echo "nlink after: $after"
4958
4959         cleanup_print_lfs_df
4960 }
4961 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
4962
4963 test_51d() {
4964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4965         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
4966
4967         test_mkdir $DIR/$tdir
4968         createmany -o $DIR/$tdir/t- 1000
4969         $LFS getstripe $DIR/$tdir > $TMP/$tfile
4970         for N in $(seq 0 $((OSTCOUNT - 1))); do
4971                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
4972                         END { printf("%0.0f", objs) }' $TMP/$tfile)
4973                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
4974                         '($1 == '$N') { objs += 1 } \
4975                         END { printf("%0.0f", objs) }')
4976                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
4977         done
4978         unlinkmany $DIR/$tdir/t- 1000
4979
4980         NLAST=0
4981         for N in $(seq 1 $((OSTCOUNT - 1))); do
4982                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
4983                         error "OST $N has less objects vs OST $NLAST" \
4984                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4985                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
4986                         error "OST $N has less objects vs OST $NLAST" \
4987                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4988
4989                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
4990                         error "OST $N has less #0 objects vs OST $NLAST" \
4991                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4992                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
4993                         error "OST $N has less #0 objects vs OST $NLAST" \
4994                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4995                 NLAST=$N
4996         done
4997         rm -f $TMP/$tfile
4998 }
4999 run_test 51d "check object distribution"
5000
5001 test_51e() {
5002         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5003                 skip_env "ldiskfs only test"
5004         fi
5005
5006         test_mkdir -c1 $DIR/$tdir
5007         test_mkdir -c1 $DIR/$tdir/d0
5008
5009         touch $DIR/$tdir/d0/foo
5010         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5011                 error "file exceed 65000 nlink limit!"
5012         unlinkmany $DIR/$tdir/d0/f- 65001
5013         return 0
5014 }
5015 run_test 51e "check file nlink limit"
5016
5017 test_51f() {
5018         test_mkdir $DIR/$tdir
5019
5020         local max=100000
5021         local ulimit_old=$(ulimit -n)
5022         local spare=20 # number of spare fd's for scripts/libraries, etc.
5023         local mdt=$($LFS getstripe -m $DIR/$tdir)
5024         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5025
5026         echo "MDT$mdt numfree=$numfree, max=$max"
5027         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5028         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5029                 while ! ulimit -n $((numfree + spare)); do
5030                         numfree=$((numfree * 3 / 4))
5031                 done
5032                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5033         else
5034                 echo "left ulimit at $ulimit_old"
5035         fi
5036
5037         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5038                 unlinkmany $DIR/$tdir/f $numfree
5039                 error "create+open $numfree files in $DIR/$tdir failed"
5040         }
5041         ulimit -n $ulimit_old
5042
5043         # if createmany exits at 120s there will be fewer than $numfree files
5044         unlinkmany $DIR/$tdir/f $numfree || true
5045 }
5046 run_test 51f "check many open files limit"
5047
5048 test_52a() {
5049         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5050         test_mkdir $DIR/$tdir
5051         touch $DIR/$tdir/foo
5052         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5053         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5054         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5055         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5056         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5057                                         error "link worked"
5058         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5059         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5060         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5061                                                      error "lsattr"
5062         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5063         cp -r $DIR/$tdir $TMP/
5064         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5065 }
5066 run_test 52a "append-only flag test (should return errors)"
5067
5068 test_52b() {
5069         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5070         test_mkdir $DIR/$tdir
5071         touch $DIR/$tdir/foo
5072         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5073         cat test > $DIR/$tdir/foo && error "cat test worked"
5074         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5075         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5076         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5077                                         error "link worked"
5078         echo foo >> $DIR/$tdir/foo && error "echo worked"
5079         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5080         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5081         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5082         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5083                                                         error "lsattr"
5084         chattr -i $DIR/$tdir/foo || error "chattr failed"
5085
5086         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5087 }
5088 run_test 52b "immutable flag test (should return errors) ======="
5089
5090 test_53() {
5091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5092         remote_mds_nodsh && skip "remote MDS with nodsh"
5093         remote_ost_nodsh && skip "remote OST with nodsh"
5094
5095         local param
5096         local param_seq
5097         local ostname
5098         local mds_last
5099         local mds_last_seq
5100         local ost_last
5101         local ost_last_seq
5102         local ost_last_id
5103         local ostnum
5104         local node
5105         local found=false
5106         local support_last_seq=true
5107
5108         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5109                 support_last_seq=false
5110
5111         # only test MDT0000
5112         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5113         local value
5114         for value in $(do_facet $SINGLEMDS \
5115                        $LCTL get_param osc.$mdtosc.prealloc_last_id) ; do
5116                 param=$(echo ${value[0]} | cut -d "=" -f1)
5117                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5118
5119                 if $support_last_seq; then
5120                         param_seq=$(echo $param |
5121                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5122                         mds_last_seq=$(do_facet $SINGLEMDS \
5123                                        $LCTL get_param -n $param_seq)
5124                 fi
5125                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5126
5127                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5128                 node=$(facet_active_host ost$((ostnum+1)))
5129                 param="obdfilter.$ostname.last_id"
5130                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5131                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5132                         ost_last_id=$ost_last
5133
5134                         if $support_last_seq; then
5135                                 ost_last_id=$(echo $ost_last |
5136                                               awk -F':' '{print $2}' |
5137                                               sed -e "s/^0x//g")
5138                                 ost_last_seq=$(echo $ost_last |
5139                                                awk -F':' '{print $1}')
5140                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5141                         fi
5142
5143                         if [[ $ost_last_id != $mds_last ]]; then
5144                                 error "$ost_last_id != $mds_last"
5145                         else
5146                                 found=true
5147                                 break
5148                         fi
5149                 done
5150         done
5151         $found || error "can not match last_seq/last_id for $mdtosc"
5152         return 0
5153 }
5154 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5155
5156 test_54a() {
5157         perl -MSocket -e ';' || skip "no Socket perl module installed"
5158
5159         $SOCKETSERVER $DIR/socket ||
5160                 error "$SOCKETSERVER $DIR/socket failed: $?"
5161         $SOCKETCLIENT $DIR/socket ||
5162                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5163         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5164 }
5165 run_test 54a "unix domain socket test =========================="
5166
5167 test_54b() {
5168         f="$DIR/f54b"
5169         mknod $f c 1 3
5170         chmod 0666 $f
5171         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5172 }
5173 run_test 54b "char device works in lustre ======================"
5174
5175 find_loop_dev() {
5176         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5177         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5178         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5179
5180         for i in $(seq 3 7); do
5181                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5182                 LOOPDEV=$LOOPBASE$i
5183                 LOOPNUM=$i
5184                 break
5185         done
5186 }
5187
5188 cleanup_54c() {
5189         local rc=0
5190         loopdev="$DIR/loop54c"
5191
5192         trap 0
5193         $UMOUNT $DIR/$tdir || rc=$?
5194         losetup -d $loopdev || true
5195         losetup -d $LOOPDEV || true
5196         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5197         return $rc
5198 }
5199
5200 test_54c() {
5201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5202
5203         loopdev="$DIR/loop54c"
5204
5205         find_loop_dev
5206         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5207         trap cleanup_54c EXIT
5208         mknod $loopdev b 7 $LOOPNUM
5209         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5210         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5211         losetup $loopdev $DIR/$tfile ||
5212                 error "can't set up $loopdev for $DIR/$tfile"
5213         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5214         test_mkdir $DIR/$tdir
5215         mount -t ext2 $loopdev $DIR/$tdir ||
5216                 error "error mounting $loopdev on $DIR/$tdir"
5217         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5218                 error "dd write"
5219         df $DIR/$tdir
5220         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5221                 error "dd read"
5222         cleanup_54c
5223 }
5224 run_test 54c "block device works in lustre ====================="
5225
5226 test_54d() {
5227         f="$DIR/f54d"
5228         string="aaaaaa"
5229         mknod $f p
5230         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5231 }
5232 run_test 54d "fifo device works in lustre ======================"
5233
5234 test_54e() {
5235         f="$DIR/f54e"
5236         string="aaaaaa"
5237         cp -aL /dev/console $f
5238         echo $string > $f || error "echo $string to $f failed"
5239 }
5240 run_test 54e "console/tty device works in lustre ======================"
5241
5242 test_56a() {
5243         local numfiles=3
5244         local dir=$DIR/$tdir
5245
5246         rm -rf $dir
5247         test_mkdir -p $dir/dir
5248         for i in $(seq $numfiles); do
5249                 touch $dir/file$i
5250                 touch $dir/dir/file$i
5251         done
5252
5253         local numcomp=$($LFS getstripe --component-count $dir)
5254
5255         [[ $numcomp == 0 ]] && numcomp=1
5256
5257         # test lfs getstripe with --recursive
5258         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5259
5260         [[ $filenum -eq $((numfiles * 2)) ]] ||
5261                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5262         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5263         [[ $filenum -eq $numfiles ]] ||
5264                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5265         echo "$LFS getstripe showed obdidx or l_ost_idx"
5266
5267         # test lfs getstripe with file instead of dir
5268         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5269         [[ $filenum -eq 1 ]] ||
5270                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5271         echo "$LFS getstripe file1 passed"
5272
5273         #test lfs getstripe with --verbose
5274         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5275         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5276                 error "$LFS getstripe --verbose $dir: "\
5277                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5278         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5279                 error "$LFS getstripe $dir: showed lmm_magic"
5280
5281         #test lfs getstripe with -v prints lmm_fid
5282         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5283         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5284                 error "$LFS getstripe -v $dir: "\
5285                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5286         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5287                 error "$LFS getstripe $dir: showed lmm_fid by default"
5288         echo "$LFS getstripe --verbose passed"
5289
5290         #check for FID information
5291         local fid1=$($LFS getstripe --fid $dir/file1)
5292         local fid2=$($LFS getstripe --verbose $dir/file1 |
5293                      awk '/lmm_fid: / { print $2; exit; }')
5294         local fid3=$($LFS path2fid $dir/file1)
5295
5296         [ "$fid1" != "$fid2" ] &&
5297                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5298         [ "$fid1" != "$fid3" ] &&
5299                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5300         echo "$LFS getstripe --fid passed"
5301
5302         #test lfs getstripe with --obd
5303         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5304                 error "$LFS getstripe --obd wrong_uuid: should return error"
5305
5306         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5307
5308         local ostidx=1
5309         local obduuid=$(ostuuid_from_index $ostidx)
5310         local found=$($LFS getstripe -r --obd $obduuid $dir |
5311                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5312
5313         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5314         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5315                 ((filenum--))
5316         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5317                 ((filenum--))
5318
5319         [[ $found -eq $filenum ]] ||
5320                 error "$LFS getstripe --obd: found $found expect $filenum"
5321         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5322                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5323                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5324                 error "$LFS getstripe --obd: should not show file on other obd"
5325         echo "$LFS getstripe --obd passed"
5326 }
5327 run_test 56a "check $LFS getstripe"
5328
5329 test_56b() {
5330         local dir=$DIR/$tdir
5331         local numdirs=3
5332
5333         test_mkdir $dir
5334         for i in $(seq $numdirs); do
5335                 test_mkdir $dir/dir$i
5336         done
5337
5338         # test lfs getdirstripe default mode is non-recursion, which is
5339         # different from lfs getstripe
5340         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5341
5342         [[ $dircnt -eq 1 ]] ||
5343                 error "$LFS getdirstripe: found $dircnt, not 1"
5344         dircnt=$($LFS getdirstripe --recursive $dir |
5345                 grep -c lmv_stripe_count)
5346         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5347                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5348 }
5349 run_test 56b "check $LFS getdirstripe"
5350
5351 test_56c() {
5352         remote_ost_nodsh && skip "remote OST with nodsh"
5353
5354         local ost_idx=0
5355         local ost_name=$(ostname_from_index $ost_idx)
5356         local old_status=$(ost_dev_status $ost_idx)
5357
5358         [[ -z "$old_status" ]] ||
5359                 skip_env "OST $ost_name is in $old_status status"
5360
5361         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5362         sleep_maxage
5363
5364         local new_status=$(ost_dev_status $ost_idx)
5365
5366         [[ "$new_status" = "D" ]] ||
5367                 error "OST $ost_name is in status of '$new_status', not 'D'"
5368
5369         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5370         sleep_maxage
5371
5372         new_status=$(ost_dev_status $ost_idx)
5373         [[ -z "$new_status" ]] ||
5374                 error "OST $ost_name is in status of '$new_status', not ''"
5375 }
5376 run_test 56c "check 'lfs df' showing device status"
5377
5378 NUMFILES=3
5379 NUMDIRS=3
5380 setup_56() {
5381         local local_tdir="$1"
5382         local local_numfiles="$2"
5383         local local_numdirs="$3"
5384         local dir_params="$4"
5385         local dir_stripe_params="$5"
5386
5387         if [ ! -d "$local_tdir" ] ; then
5388                 test_mkdir -p $dir_stripe_params $local_tdir
5389                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5390                 for i in $(seq $local_numfiles) ; do
5391                         touch $local_tdir/file$i
5392                 done
5393                 for i in $(seq $local_numdirs) ; do
5394                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5395                         for j in $(seq $local_numfiles) ; do
5396                                 touch $local_tdir/dir$i/file$j
5397                         done
5398                 done
5399         fi
5400 }
5401
5402 setup_56_special() {
5403         local local_tdir=$1
5404         local local_numfiles=$2
5405         local local_numdirs=$3
5406
5407         setup_56 $local_tdir $local_numfiles $local_numdirs
5408
5409         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5410                 for i in $(seq $local_numfiles) ; do
5411                         mknod $local_tdir/loop${i}b b 7 $i
5412                         mknod $local_tdir/null${i}c c 1 3
5413                         ln -s $local_tdir/file1 $local_tdir/link${i}
5414                 done
5415                 for i in $(seq $local_numdirs) ; do
5416                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5417                         mknod $local_tdir/dir$i/null${i}c c 1 3
5418                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5419                 done
5420         fi
5421 }
5422
5423 test_56g() {
5424         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5425         local expected=$(($NUMDIRS + 2))
5426
5427         setup_56 $dir $NUMFILES $NUMDIRS
5428
5429         # test lfs find with -name
5430         for i in $(seq $NUMFILES) ; do
5431                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5432
5433                 [ $nums -eq $expected ] ||
5434                         error "lfs find -name '*$i' $dir wrong: "\
5435                               "found $nums, expected $expected"
5436         done
5437 }
5438 run_test 56g "check lfs find -name"
5439
5440 test_56h() {
5441         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5442         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5443
5444         setup_56 $dir $NUMFILES $NUMDIRS
5445
5446         # test lfs find with ! -name
5447         for i in $(seq $NUMFILES) ; do
5448                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5449
5450                 [ $nums -eq $expected ] ||
5451                         error "lfs find ! -name '*$i' $dir wrong: "\
5452                               "found $nums, expected $expected"
5453         done
5454 }
5455 run_test 56h "check lfs find ! -name"
5456
5457 test_56i() {
5458         local dir=$DIR/$tdir
5459
5460         test_mkdir $dir
5461
5462         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5463         local out=$($cmd)
5464
5465         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5466 }
5467 run_test 56i "check 'lfs find -ost UUID' skips directories"
5468
5469 test_56j() {
5470         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5471
5472         setup_56_special $dir $NUMFILES $NUMDIRS
5473
5474         local expected=$((NUMDIRS + 1))
5475         local cmd="$LFS find -type d $dir"
5476         local nums=$($cmd | wc -l)
5477
5478         [ $nums -eq $expected ] ||
5479                 error "'$cmd' wrong: found $nums, expected $expected"
5480 }
5481 run_test 56j "check lfs find -type d"
5482
5483 test_56k() {
5484         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5485
5486         setup_56_special $dir $NUMFILES $NUMDIRS
5487
5488         local expected=$(((NUMDIRS + 1) * NUMFILES))
5489         local cmd="$LFS find -type f $dir"
5490         local nums=$($cmd | wc -l)
5491
5492         [ $nums -eq $expected ] ||
5493                 error "'$cmd' wrong: found $nums, expected $expected"
5494 }
5495 run_test 56k "check lfs find -type f"
5496
5497 test_56l() {
5498         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5499
5500         setup_56_special $dir $NUMFILES $NUMDIRS
5501
5502         local expected=$((NUMDIRS + NUMFILES))
5503         local cmd="$LFS find -type b $dir"
5504         local nums=$($cmd | wc -l)
5505
5506         [ $nums -eq $expected ] ||
5507                 error "'$cmd' wrong: found $nums, expected $expected"
5508 }
5509 run_test 56l "check lfs find -type b"
5510
5511 test_56m() {
5512         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5513
5514         setup_56_special $dir $NUMFILES $NUMDIRS
5515
5516         local expected=$((NUMDIRS + NUMFILES))
5517         local cmd="$LFS find -type c $dir"
5518         local nums=$($cmd | wc -l)
5519         [ $nums -eq $expected ] ||
5520                 error "'$cmd' wrong: found $nums, expected $expected"
5521 }
5522 run_test 56m "check lfs find -type c"
5523
5524 test_56n() {
5525         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5526         setup_56_special $dir $NUMFILES $NUMDIRS
5527
5528         local expected=$((NUMDIRS + NUMFILES))
5529         local cmd="$LFS find -type l $dir"
5530         local nums=$($cmd | wc -l)
5531
5532         [ $nums -eq $expected ] ||
5533                 error "'$cmd' wrong: found $nums, expected $expected"
5534 }
5535 run_test 56n "check lfs find -type l"
5536
5537 test_56o() {
5538         local dir=$DIR/$tdir
5539
5540         setup_56 $dir $NUMFILES $NUMDIRS
5541         utime $dir/file1 > /dev/null || error "utime (1)"
5542         utime $dir/file2 > /dev/null || error "utime (2)"
5543         utime $dir/dir1 > /dev/null || error "utime (3)"
5544         utime $dir/dir2 > /dev/null || error "utime (4)"
5545         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5546         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5547
5548         local expected=4
5549         local nums=$($LFS find -mtime +0 $dir | wc -l)
5550
5551         [ $nums -eq $expected ] ||
5552                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5553
5554         expected=12
5555         cmd="$LFS find -mtime 0 $dir"
5556         nums=$($cmd | wc -l)
5557         [ $nums -eq $expected ] ||
5558                 error "'$cmd' wrong: found $nums, expected $expected"
5559 }
5560 run_test 56o "check lfs find -mtime for old files"
5561
5562 test_56ob() {
5563         local dir=$DIR/$tdir
5564         local expected=1
5565         local count=0
5566
5567         # just to make sure there is something that won't be found
5568         test_mkdir $dir
5569         touch $dir/$tfile.now
5570
5571         for age in year week day hour min; do
5572                 count=$((count + 1))
5573
5574                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5575                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5576                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5577
5578                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5579                 local nums=$($cmd | wc -l)
5580                 [ $nums -eq $expected ] ||
5581                         error "'$cmd' wrong: found $nums, expected $expected"
5582
5583                 cmd="$LFS find $dir -atime $count${age:0:1}"
5584                 nums=$($cmd | wc -l)
5585                 [ $nums -eq $expected ] ||
5586                         error "'$cmd' wrong: found $nums, expected $expected"
5587         done
5588
5589         sleep 2
5590         cmd="$LFS find $dir -ctime +1s -type f"
5591         nums=$($cmd | wc -l)
5592         (( $nums == $count * 2 + 1)) ||
5593                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5594 }
5595 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5596
5597 test_56p() {
5598         [ $RUNAS_ID -eq $UID ] &&
5599                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5600
5601         local dir=$DIR/$tdir
5602
5603         setup_56 $dir $NUMFILES $NUMDIRS
5604         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5605
5606         local expected=$NUMFILES
5607         local cmd="$LFS find -uid $RUNAS_ID $dir"
5608         local nums=$($cmd | wc -l)
5609
5610         [ $nums -eq $expected ] ||
5611                 error "'$cmd' wrong: found $nums, expected $expected"
5612
5613         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5614         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5615         nums=$($cmd | wc -l)
5616         [ $nums -eq $expected ] ||
5617                 error "'$cmd' wrong: found $nums, expected $expected"
5618 }
5619 run_test 56p "check lfs find -uid and ! -uid"
5620
5621 test_56q() {
5622         [ $RUNAS_ID -eq $UID ] &&
5623                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5624
5625         local dir=$DIR/$tdir
5626
5627         setup_56 $dir $NUMFILES $NUMDIRS
5628         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5629
5630         local expected=$NUMFILES
5631         local cmd="$LFS find -gid $RUNAS_GID $dir"
5632         local nums=$($cmd | wc -l)
5633
5634         [ $nums -eq $expected ] ||
5635                 error "'$cmd' wrong: found $nums, expected $expected"
5636
5637         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5638         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5639         nums=$($cmd | wc -l)
5640         [ $nums -eq $expected ] ||
5641                 error "'$cmd' wrong: found $nums, expected $expected"
5642 }
5643 run_test 56q "check lfs find -gid and ! -gid"
5644
5645 test_56r() {
5646         local dir=$DIR/$tdir
5647
5648         setup_56 $dir $NUMFILES $NUMDIRS
5649
5650         local expected=12
5651         local cmd="$LFS find -size 0 -type f $dir"
5652         local nums=$($cmd | wc -l)
5653
5654         [ $nums -eq $expected ] ||
5655                 error "'$cmd' wrong: found $nums, expected $expected"
5656         expected=0
5657         cmd="$LFS find ! -size 0 -type f $dir"
5658         nums=$($cmd | wc -l)
5659         [ $nums -eq $expected ] ||
5660                 error "'$cmd' wrong: found $nums, expected $expected"
5661         echo "test" > $dir/$tfile
5662         echo "test2" > $dir/$tfile.2 && sync
5663         expected=1
5664         cmd="$LFS find -size 5 -type f $dir"
5665         nums=$($cmd | wc -l)
5666         [ $nums -eq $expected ] ||
5667                 error "'$cmd' wrong: found $nums, expected $expected"
5668         expected=1
5669         cmd="$LFS find -size +5 -type f $dir"
5670         nums=$($cmd | wc -l)
5671         [ $nums -eq $expected ] ||
5672                 error "'$cmd' wrong: found $nums, expected $expected"
5673         expected=2
5674         cmd="$LFS find -size +0 -type f $dir"
5675         nums=$($cmd | wc -l)
5676         [ $nums -eq $expected ] ||
5677                 error "'$cmd' wrong: found $nums, expected $expected"
5678         expected=2
5679         cmd="$LFS find ! -size -5 -type f $dir"
5680         nums=$($cmd | wc -l)
5681         [ $nums -eq $expected ] ||
5682                 error "'$cmd' wrong: found $nums, expected $expected"
5683         expected=12
5684         cmd="$LFS find -size -5 -type f $dir"
5685         nums=$($cmd | wc -l)
5686         [ $nums -eq $expected ] ||
5687                 error "'$cmd' wrong: found $nums, expected $expected"
5688 }
5689 run_test 56r "check lfs find -size works"
5690
5691 test_56s() { # LU-611 #LU-9369
5692         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
5693
5694         local dir=$DIR/$tdir
5695         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
5696
5697         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
5698         for i in $(seq $NUMDIRS); do
5699                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
5700         done
5701
5702         local expected=$NUMDIRS
5703         local cmd="$LFS find -c $OSTCOUNT $dir"
5704         local nums=$($cmd | wc -l)
5705
5706         [ $nums -eq $expected ] || {
5707                 $LFS getstripe -R $dir
5708                 error "'$cmd' wrong: found $nums, expected $expected"
5709         }
5710
5711         expected=$((NUMDIRS + onestripe))
5712         cmd="$LFS find -stripe-count +0 -type f $dir"
5713         nums=$($cmd | wc -l)
5714         [ $nums -eq $expected ] || {
5715                 $LFS getstripe -R $dir
5716                 error "'$cmd' wrong: found $nums, expected $expected"
5717         }
5718
5719         expected=$onestripe
5720         cmd="$LFS find -stripe-count 1 -type f $dir"
5721         nums=$($cmd | wc -l)
5722         [ $nums -eq $expected ] || {
5723                 $LFS getstripe -R $dir
5724                 error "'$cmd' wrong: found $nums, expected $expected"
5725         }
5726
5727         cmd="$LFS find -stripe-count -2 -type f $dir"
5728         nums=$($cmd | wc -l)
5729         [ $nums -eq $expected ] || {
5730                 $LFS getstripe -R $dir
5731                 error "'$cmd' wrong: found $nums, expected $expected"
5732         }
5733
5734         expected=0
5735         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
5736         nums=$($cmd | wc -l)
5737         [ $nums -eq $expected ] || {
5738                 $LFS getstripe -R $dir
5739                 error "'$cmd' wrong: found $nums, expected $expected"
5740         }
5741 }
5742 run_test 56s "check lfs find -stripe-count works"
5743
5744 test_56t() { # LU-611 #LU-9369
5745         local dir=$DIR/$tdir
5746
5747         setup_56 $dir 0 $NUMDIRS
5748         for i in $(seq $NUMDIRS); do
5749                 $LFS setstripe -S 8M $dir/dir$i/$tfile
5750         done
5751
5752         local expected=$NUMDIRS
5753         local cmd="$LFS find -S 8M $dir"
5754         local nums=$($cmd | wc -l)
5755
5756         [ $nums -eq $expected ] || {
5757                 $LFS getstripe -R $dir
5758                 error "'$cmd' wrong: found $nums, expected $expected"
5759         }
5760         rm -rf $dir
5761
5762         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
5763
5764         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
5765
5766         expected=$(((NUMDIRS + 1) * NUMFILES))
5767         cmd="$LFS find -stripe-size 512k -type f $dir"
5768         nums=$($cmd | wc -l)
5769         [ $nums -eq $expected ] ||
5770                 error "'$cmd' wrong: found $nums, expected $expected"
5771
5772         cmd="$LFS find -stripe-size +320k -type f $dir"
5773         nums=$($cmd | wc -l)
5774         [ $nums -eq $expected ] ||
5775                 error "'$cmd' wrong: found $nums, expected $expected"
5776
5777         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
5778         cmd="$LFS find -stripe-size +200k -type f $dir"
5779         nums=$($cmd | wc -l)
5780         [ $nums -eq $expected ] ||
5781                 error "'$cmd' wrong: found $nums, expected $expected"
5782
5783         cmd="$LFS find -stripe-size -640k -type f $dir"
5784         nums=$($cmd | wc -l)
5785         [ $nums -eq $expected ] ||
5786                 error "'$cmd' wrong: found $nums, expected $expected"
5787
5788         expected=4
5789         cmd="$LFS find -stripe-size 256k -type f $dir"
5790         nums=$($cmd | wc -l)
5791         [ $nums -eq $expected ] ||
5792                 error "'$cmd' wrong: found $nums, expected $expected"
5793
5794         cmd="$LFS find -stripe-size -320k -type f $dir"
5795         nums=$($cmd | wc -l)
5796         [ $nums -eq $expected ] ||
5797                 error "'$cmd' wrong: found $nums, expected $expected"
5798
5799         expected=0
5800         cmd="$LFS find -stripe-size 1024k -type f $dir"
5801         nums=$($cmd | wc -l)
5802         [ $nums -eq $expected ] ||
5803                 error "'$cmd' wrong: found $nums, expected $expected"
5804 }
5805 run_test 56t "check lfs find -stripe-size works"
5806
5807 test_56u() { # LU-611
5808         local dir=$DIR/$tdir
5809
5810         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
5811
5812         if [[ $OSTCOUNT -gt 1 ]]; then
5813                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
5814                 onestripe=4
5815         else
5816                 onestripe=0
5817         fi
5818
5819         local expected=$(((NUMDIRS + 1) * NUMFILES))
5820         local cmd="$LFS find -stripe-index 0 -type f $dir"
5821         local nums=$($cmd | wc -l)
5822
5823         [ $nums -eq $expected ] ||
5824                 error "'$cmd' wrong: found $nums, expected $expected"
5825
5826         expected=$onestripe
5827         cmd="$LFS find -stripe-index 1 -type f $dir"
5828         nums=$($cmd | wc -l)
5829         [ $nums -eq $expected ] ||
5830                 error "'$cmd' wrong: found $nums, expected $expected"
5831
5832         cmd="$LFS find ! -stripe-index 0 -type f $dir"
5833         nums=$($cmd | wc -l)
5834         [ $nums -eq $expected ] ||
5835                 error "'$cmd' wrong: found $nums, expected $expected"
5836
5837         expected=0
5838         # This should produce an error and not return any files
5839         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
5840         nums=$($cmd 2>/dev/null | wc -l)
5841         [ $nums -eq $expected ] ||
5842                 error "'$cmd' wrong: found $nums, expected $expected"
5843
5844         if [[ $OSTCOUNT -gt 1 ]]; then
5845                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
5846                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
5847                 nums=$($cmd | wc -l)
5848                 [ $nums -eq $expected ] ||
5849                         error "'$cmd' wrong: found $nums, expected $expected"
5850         fi
5851 }
5852 run_test 56u "check lfs find -stripe-index works"
5853
5854 test_56v() {
5855         local mdt_idx=0
5856         local dir=$DIR/$tdir
5857
5858         setup_56 $dir $NUMFILES $NUMDIRS
5859
5860         UUID=$(mdtuuid_from_index $mdt_idx $dir)
5861         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
5862
5863         for file in $($LFS find -m $UUID $dir); do
5864                 file_midx=$($LFS getstripe -m $file)
5865                 [ $file_midx -eq $mdt_idx ] ||
5866                         error "lfs find -m $UUID != getstripe -m $file_midx"
5867         done
5868 }
5869 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
5870
5871 test_56w() {
5872         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5873         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5874
5875         local dir=$DIR/$tdir
5876
5877         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
5878
5879         local stripe_size=$($LFS getstripe -S -d $dir) ||
5880                 error "$LFS getstripe -S -d $dir failed"
5881         stripe_size=${stripe_size%% *}
5882
5883         local file_size=$((stripe_size * OSTCOUNT))
5884         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
5885         local required_space=$((file_num * file_size))
5886         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
5887                            head -n1)
5888         [[ $free_space -le $((required_space / 1024)) ]] &&
5889                 skip_env "need $required_space, have $free_space kbytes"
5890
5891         local dd_bs=65536
5892         local dd_count=$((file_size / dd_bs))
5893
5894         # write data into the files
5895         local i
5896         local j
5897         local file
5898
5899         for i in $(seq $NUMFILES); do
5900                 file=$dir/file$i
5901                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5902                         error "write data into $file failed"
5903         done
5904         for i in $(seq $NUMDIRS); do
5905                 for j in $(seq $NUMFILES); do
5906                         file=$dir/dir$i/file$j
5907                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5908                                 error "write data into $file failed"
5909                 done
5910         done
5911
5912         # $LFS_MIGRATE will fail if hard link migration is unsupported
5913         if [[ $(lustre_version_code mds1) -gt $(version_code 2.5.55) ]]; then
5914                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
5915                         error "creating links to $dir/dir1/file1 failed"
5916         fi
5917
5918         local expected=-1
5919
5920         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
5921
5922         # lfs_migrate file
5923         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
5924
5925         echo "$cmd"
5926         eval $cmd || error "$cmd failed"
5927
5928         check_stripe_count $dir/file1 $expected
5929
5930         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
5931         then
5932                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
5933                 # OST 1 if it is on OST 0. This file is small enough to
5934                 # be on only one stripe.
5935                 file=$dir/migr_1_ost
5936                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
5937                         error "write data into $file failed"
5938                 local obdidx=$($LFS getstripe -i $file)
5939                 local oldmd5=$(md5sum $file)
5940                 local newobdidx=0
5941
5942                 [[ $obdidx -eq 0 ]] && newobdidx=1
5943                 cmd="$LFS migrate -i $newobdidx $file"
5944                 echo $cmd
5945                 eval $cmd || error "$cmd failed"
5946
5947                 local realobdix=$($LFS getstripe -i $file)
5948                 local newmd5=$(md5sum $file)
5949
5950                 [[ $newobdidx -ne $realobdix ]] &&
5951                         error "new OST is different (was=$obdidx, "\
5952                               "wanted=$newobdidx, got=$realobdix)"
5953                 [[ "$oldmd5" != "$newmd5" ]] &&
5954                         error "md5sum differ: $oldmd5, $newmd5"
5955         fi
5956
5957         # lfs_migrate dir
5958         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
5959         echo "$cmd"
5960         eval $cmd || error "$cmd failed"
5961
5962         for j in $(seq $NUMFILES); do
5963                 check_stripe_count $dir/dir1/file$j $expected
5964         done
5965
5966         # lfs_migrate works with lfs find
5967         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
5968              $LFS_MIGRATE -y -c $expected"
5969         echo "$cmd"
5970         eval $cmd || error "$cmd failed"
5971
5972         for i in $(seq 2 $NUMFILES); do
5973                 check_stripe_count $dir/file$i $expected
5974         done
5975         for i in $(seq 2 $NUMDIRS); do
5976                 for j in $(seq $NUMFILES); do
5977                 check_stripe_count $dir/dir$i/file$j $expected
5978                 done
5979         done
5980 }
5981 run_test 56w "check lfs_migrate -c stripe_count works"
5982
5983 test_56wb() {
5984         local file1=$DIR/$tdir/file1
5985         local create_pool=false
5986         local initial_pool=$($LFS getstripe -p $DIR)
5987         local pool_list=()
5988         local pool=""
5989
5990         echo -n "Creating test dir..."
5991         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5992         echo "done."
5993
5994         echo -n "Creating test file..."
5995         touch $file1 || error "cannot create file"
5996         echo "done."
5997
5998         echo -n "Detecting existing pools..."
5999         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6000
6001         if [ ${#pool_list[@]} -gt 0 ]; then
6002                 echo "${pool_list[@]}"
6003                 for thispool in "${pool_list[@]}"; do
6004                         if [[ -z "$initial_pool" ||
6005                               "$initial_pool" != "$thispool" ]]; then
6006                                 pool="$thispool"
6007                                 echo "Using existing pool '$pool'"
6008                                 break
6009                         fi
6010                 done
6011         else
6012                 echo "none detected."
6013         fi
6014         if [ -z "$pool" ]; then
6015                 pool=${POOL:-testpool}
6016                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6017                 echo -n "Creating pool '$pool'..."
6018                 create_pool=true
6019                 pool_add $pool &> /dev/null ||
6020                         error "pool_add failed"
6021                 echo "done."
6022
6023                 echo -n "Adding target to pool..."
6024                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6025                         error "pool_add_targets failed"
6026                 echo "done."
6027         fi
6028
6029         echo -n "Setting pool using -p option..."
6030         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6031                 error "migrate failed rc = $?"
6032         echo "done."
6033
6034         echo -n "Verifying test file is in pool after migrating..."
6035         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6036                 error "file was not migrated to pool $pool"
6037         echo "done."
6038
6039         echo -n "Removing test file from pool '$pool'..."
6040         $LFS migrate $file1 &> /dev/null ||
6041                 error "cannot remove from pool"
6042         [ "$($LFS getstripe -p $file1)" ] &&
6043                 error "pool still set"
6044         echo "done."
6045
6046         echo -n "Setting pool using --pool option..."
6047         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6048                 error "migrate failed rc = $?"
6049         echo "done."
6050
6051         # Clean up
6052         rm -f $file1
6053         if $create_pool; then
6054                 destroy_test_pools 2> /dev/null ||
6055                         error "destroy test pools failed"
6056         fi
6057 }
6058 run_test 56wb "check lfs_migrate pool support"
6059
6060 test_56wc() {
6061         local file1="$DIR/$tdir/file1"
6062
6063         echo -n "Creating test dir..."
6064         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6065         local def_stripe_size=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6066         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6067                 error "cannot set stripe"
6068         echo "done"
6069
6070         echo -n "Setting initial stripe for test file..."
6071         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6072                 error "cannot set stripe"
6073         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6074                 error "stripe size not set"
6075         echo "done."
6076
6077         # File currently set to -S 512K -c 1
6078
6079         # Ensure -c and -S options are rejected when -R is set
6080         echo -n "Verifying incompatible options are detected..."
6081         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6082                 error "incompatible -c and -R options not detected"
6083         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6084                 error "incompatible -S and -R options not detected"
6085         echo "done."
6086
6087         # Ensure unrecognized options are passed through to 'lfs migrate'
6088         echo -n "Verifying -S option is passed through to lfs migrate..."
6089         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6090                 error "migration failed"
6091         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
6092                 error "file was not restriped"
6093         echo "done."
6094
6095         # File currently set to -S 1M -c 1
6096
6097         # Ensure long options are supported
6098         echo -n "Verifying long options supported..."
6099         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6100                 error "long option without argument not supported"
6101         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6102                 error "long option with argument not supported"
6103         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6104                 error "file not restriped with --stripe-size option"
6105         echo "done."
6106
6107         # File currently set to -S 512K -c 1
6108
6109         if [ "$OSTCOUNT" -gt 1 ]; then
6110                 echo -n "Verifying explicit stripe count can be set..."
6111                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6112                         error "migrate failed"
6113                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
6114                         error "file not restriped to explicit count"
6115                 echo "done."
6116         fi
6117
6118         # File currently set to -S 512K -c 1 or -S 512K -c 2
6119
6120         # Ensure parent striping is used if -R is set, and no stripe
6121         # count or size is specified
6122         echo -n "Setting stripe for parent directory..."
6123         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6124                 error "cannot set stripe"
6125         echo "done."
6126
6127         echo -n "Verifying restripe option uses parent stripe settings..."
6128         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6129                 error "migrate failed"
6130         [ $($LFS getstripe -S "$file1") -eq $def_stripe_size ] ||
6131                 error "file not restriped to parent settings"
6132         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
6133                 error "file not restriped to parent settings"
6134         echo "done."
6135
6136         # File currently set to -S 1M -c 1
6137
6138         # Ensure striping is preserved if -R is not set, and no stripe
6139         # count or size is specified
6140         echo -n "Verifying striping size preserved when not specified..."
6141         local orig_stripe_size=$($LFS getstripe -S "$file1" 2>/dev/null)
6142         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6143                 error "cannot set stripe on parent directory"
6144         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6145                 error "migrate failed"
6146         [ $($LFS getstripe -S "$file1") -eq $orig_stripe_size ] ||
6147                 error "file was restriped"
6148         echo "done."
6149
6150         # Ensure file name properly detected when final option has no argument
6151         echo -n "Verifying file name properly detected..."
6152         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6153                 error "file name interpreted as option argument"
6154         echo "done."
6155
6156         # Clean up
6157         rm -f "$file1"
6158 }
6159 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6160
6161 test_56wd() {
6162         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6163
6164         local file1=$DIR/$tdir/file1
6165
6166         echo -n "Creating test dir..."
6167         test_mkdir $DIR/$tdir || error "cannot create dir"
6168         echo "done."
6169
6170         echo -n "Creating test file..."
6171         touch $file1
6172         echo "done."
6173
6174         # Ensure 'lfs migrate' will fail by using a non-existent option,
6175         # and make sure rsync is not called to recover
6176         echo -n "Make sure --no-rsync option works..."
6177         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6178                 grep -q 'refusing to fall back to rsync' ||
6179                 error "rsync was called with --no-rsync set"
6180         echo "done."
6181
6182         # Ensure rsync is called without trying 'lfs migrate' first
6183         echo -n "Make sure --rsync option works..."
6184         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6185                 grep -q 'falling back to rsync' &&
6186                 error "lfs migrate was called with --rsync set"
6187         echo "done."
6188
6189         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6190         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6191                 grep -q 'at the same time' ||
6192                 error "--rsync and --no-rsync accepted concurrently"
6193         echo "done."
6194
6195         # Clean up
6196         rm -f $file1
6197 }
6198 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6199
6200 test_56x() {
6201         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6202         check_swap_layouts_support
6203
6204         local dir=$DIR/$tdir
6205         local ref1=/etc/passwd
6206         local file1=$dir/file1
6207
6208         test_mkdir $dir || error "creating dir $dir"
6209         $LFS setstripe -c 2 $file1
6210         cp $ref1 $file1
6211         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6212         stripe=$($LFS getstripe -c $file1)
6213         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6214         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6215
6216         # clean up
6217         rm -f $file1
6218 }
6219 run_test 56x "lfs migration support"
6220
6221 test_56xa() {
6222         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6223         check_swap_layouts_support
6224
6225         local dir=$DIR/$tdir/$testnum
6226
6227         test_mkdir -p $dir
6228
6229         local ref1=/etc/passwd
6230         local file1=$dir/file1
6231
6232         $LFS setstripe -c 2 $file1
6233         cp $ref1 $file1
6234         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6235
6236         local stripe=$($LFS getstripe -c $file1)
6237
6238         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6239         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6240
6241         # clean up
6242         rm -f $file1
6243 }
6244 run_test 56xa "lfs migration --block support"
6245
6246 check_migrate_links() {
6247         local dir="$1"
6248         local file1="$dir/file1"
6249         local begin="$2"
6250         local count="$3"
6251         local total_count=$(($begin + $count - 1))
6252         local symlink_count=10
6253         local uniq_count=10
6254
6255         if [ ! -f "$file1" ]; then
6256                 echo -n "creating initial file..."
6257                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6258                         error "cannot setstripe initial file"
6259                 echo "done"
6260
6261                 echo -n "creating symlinks..."
6262                 for s in $(seq 1 $symlink_count); do
6263                         ln -s "$file1" "$dir/slink$s" ||
6264                                 error "cannot create symlinks"
6265                 done
6266                 echo "done"
6267
6268                 echo -n "creating nonlinked files..."
6269                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6270                         error "cannot create nonlinked files"
6271                 echo "done"
6272         fi
6273
6274         # create hard links
6275         if [ ! -f "$dir/file$total_count" ]; then
6276                 echo -n "creating hard links $begin:$total_count..."
6277                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6278                         /dev/null || error "cannot create hard links"
6279                 echo "done"
6280         fi
6281
6282         echo -n "checking number of hard links listed in xattrs..."
6283         local fid=$($LFS getstripe -F "$file1")
6284         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6285
6286         echo "${#paths[*]}"
6287         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6288                         skip "hard link list has unexpected size, skipping test"
6289         fi
6290         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6291                         error "link names should exceed xattrs size"
6292         fi
6293
6294         echo -n "migrating files..."
6295         local migrate_out=$($LFS_MIGRATE -y -S '1m' $dir)
6296         local rc=$?
6297         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6298         echo "done"
6299
6300         # make sure all links have been properly migrated
6301         echo -n "verifying files..."
6302         fid=$($LFS getstripe -F "$file1") ||
6303                 error "cannot get fid for file $file1"
6304         for i in $(seq 2 $total_count); do
6305                 local fid2=$($LFS getstripe -F $dir/file$i)
6306
6307                 [ "$fid2" == "$fid" ] ||
6308                         error "migrated hard link has mismatched FID"
6309         done
6310
6311         # make sure hard links were properly detected, and migration was
6312         # performed only once for the entire link set; nonlinked files should
6313         # also be migrated
6314         local actual=$(grep -c 'done migrate' <<< "$migrate_out")
6315         local expected=$(($uniq_count + 1))
6316
6317         [ "$actual" -eq  "$expected" ] ||
6318                 error "hard links individually migrated ($actual != $expected)"
6319
6320         # make sure the correct number of hard links are present
6321         local hardlinks=$(stat -c '%h' "$file1")
6322
6323         [ $hardlinks -eq $total_count ] ||
6324                 error "num hard links $hardlinks != $total_count"
6325         echo "done"
6326
6327         return 0
6328 }
6329
6330 test_56xb() {
6331         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6332                 skip "Need MDS version at least 2.10.55"
6333
6334         local dir="$DIR/$tdir"
6335
6336         test_mkdir "$dir" || error "cannot create dir $dir"
6337
6338         echo "testing lfs migrate mode when all links fit within xattrs"
6339         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6340
6341         echo "testing rsync mode when all links fit within xattrs"
6342         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6343
6344         echo "testing lfs migrate mode when all links do not fit within xattrs"
6345         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
6346
6347         echo "testing rsync mode when all links do not fit within xattrs"
6348         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
6349
6350
6351         # clean up
6352         rm -rf $dir
6353 }
6354 run_test 56xb "lfs migration hard link support"
6355
6356 test_56xc() {
6357         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6358
6359         local dir="$DIR/$tdir"
6360
6361         test_mkdir "$dir" || error "cannot create dir $dir"
6362
6363         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
6364         echo -n "Setting initial stripe for 20MB test file..."
6365         $LFS setstripe -c 2 -i 0 "$dir/20mb" || error "cannot setstripe"
6366         echo "done"
6367         echo -n "Sizing 20MB test file..."
6368         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
6369         echo "done"
6370         echo -n "Verifying small file autostripe count is 1..."
6371         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" &> /dev/null ||
6372                 error "cannot migrate 20MB file"
6373         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
6374                 error "cannot get stripe for $dir/20mb"
6375         [ $stripe_count -eq 1 ] ||
6376                 error "unexpected stripe count $stripe_count for 20MB file"
6377         rm -f "$dir/20mb"
6378         echo "done"
6379
6380         # Test 2: File is small enough to fit within the available space on
6381         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
6382         # have at least an additional 1KB for each desired stripe for test 3
6383         echo -n "Setting stripe for 1GB test file..."
6384         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe"
6385         echo "done"
6386         echo -n "Sizing 1GB test file..."
6387         # File size is 1GB + 3KB
6388         truncate "$dir/1gb" 1073744896 &> /dev/null ||
6389                 error "cannot create 1GB test file"
6390         echo "done"
6391         echo -n "Migrating 1GB file..."
6392         $LFS_MIGRATE -y -A -C 1 "$dir/1gb" &> /dev/null ||
6393                 error "cannot migrate file"
6394         echo "done"
6395         echo -n "Verifying autostripe count is sqrt(n) + 1..."
6396         stripe_count=$($LFS getstripe -c "$dir/1gb") ||
6397                 error "cannot get stripe for $dir/1gb"
6398         [ $stripe_count -eq 2 ] ||
6399                 error "unexpected stripe count $stripe_count (expected 2)"
6400         echo "done"
6401
6402         # Test 3: File is too large to fit within the available space on
6403         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
6404         if [ $OSTCOUNT -ge 3 ]; then
6405                 # The required available space is calculated as
6406                 # file size (1GB + 3KB) / OST count (3).
6407                 local kb_per_ost=349526
6408
6409                 echo -n "Migrating 1GB file..."
6410                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" &>> \
6411                         /dev/null || error "cannot migrate file"
6412                 echo "done"
6413
6414                 stripe_count=$($LFS getstripe -c "$dir/1gb")
6415                 echo -n "Verifying autostripe count with limited space..."
6416                 [ "$stripe_count" -a $stripe_count -eq 3 ] ||
6417                         error "unexpected stripe count $stripe_count (wanted 3)"
6418                 echo "done"
6419         fi
6420
6421         # clean up
6422         rm -rf $dir
6423 }
6424 run_test 56xc "lfs migration autostripe"
6425
6426 test_56y() {
6427         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
6428                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
6429
6430         local res=""
6431         local dir=$DIR/$tdir
6432         local f1=$dir/file1
6433         local f2=$dir/file2
6434
6435         test_mkdir -p $dir || error "creating dir $dir"
6436         touch $f1 || error "creating std file $f1"
6437         $MULTIOP $f2 H2c || error "creating released file $f2"
6438
6439         # a directory can be raid0, so ask only for files
6440         res=$($LFS find $dir -L raid0 -type f | wc -l)
6441         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
6442
6443         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
6444         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
6445
6446         # only files can be released, so no need to force file search
6447         res=$($LFS find $dir -L released)
6448         [[ $res == $f2 ]] || error "search released: found $res != $f2"
6449
6450         res=$($LFS find $dir -type f \! -L released)
6451         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
6452 }
6453 run_test 56y "lfs find -L raid0|released"
6454
6455 test_56z() { # LU-4824
6456         # This checks to make sure 'lfs find' continues after errors
6457         # There are two classes of errors that should be caught:
6458         # - If multiple paths are provided, all should be searched even if one
6459         #   errors out
6460         # - If errors are encountered during the search, it should not terminate
6461         #   early
6462         local dir=$DIR/$tdir
6463         local i
6464
6465         test_mkdir $dir
6466         for i in d{0..9}; do
6467                 test_mkdir $dir/$i
6468         done
6469         touch $dir/d{0..9}/$tfile
6470         $LFS find $DIR/non_existent_dir $dir &&
6471                 error "$LFS find did not return an error"
6472         # Make a directory unsearchable. This should NOT be the last entry in
6473         # directory order.  Arbitrarily pick the 6th entry
6474         chmod 700 $($LFS find $dir -type d | sed '6!d')
6475
6476         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
6477
6478         # The user should be able to see 10 directories and 9 files
6479         [ $count == 19 ] || error "$LFS find did not continue after error"
6480 }
6481 run_test 56z "lfs find should continue after an error"
6482
6483 test_56aa() { # LU-5937
6484         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
6485
6486         local dir=$DIR/$tdir
6487
6488         mkdir $dir
6489         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
6490
6491         createmany -o $dir/striped_dir/${tfile}- 1024
6492         local dirs=$($LFS find --size +8k $dir/)
6493
6494         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
6495 }
6496 run_test 56aa "lfs find --size under striped dir"
6497
6498 test_56ab() { # LU-10705
6499         test_mkdir $DIR/$tdir
6500         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
6501         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
6502         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
6503         # Flush writes to ensure valid blocks.  Need to be more thorough for
6504         # ZFS, since blocks are not allocated/returned to client immediately.
6505         sync_all_data
6506         wait_zfs_commit ost1 2
6507         cancel_lru_locks osc
6508         ls -ls $DIR/$tdir
6509
6510         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
6511
6512         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
6513
6514         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
6515         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
6516
6517         rm -f $DIR/$tdir/$tfile.[123]
6518 }
6519 run_test 56ab "lfs find --blocks"
6520
6521 test_56ba() {
6522         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
6523                 skip "Need MDS version at least 2.10.50"
6524
6525         # Create composite files with one component
6526         local dir=$DIR/$tdir
6527
6528         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
6529         # Create composite files with three components
6530         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
6531         # Create non-composite files
6532         createmany -o $dir/${tfile}- 10
6533
6534         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
6535
6536         [[ $nfiles == 10 ]] ||
6537                 error "lfs find -E 1M found $nfiles != 10 files"
6538
6539         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
6540         [[ $nfiles == 25 ]] ||
6541                 error "lfs find ! -E 1M found $nfiles != 25 files"
6542
6543         # All files have a component that starts at 0
6544         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
6545         [[ $nfiles == 35 ]] ||
6546                 error "lfs find --component-start 0 - $nfiles != 35 files"
6547
6548         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
6549         [[ $nfiles == 15 ]] ||
6550                 error "lfs find --component-start 2M - $nfiles != 15 files"
6551
6552         # All files created here have a componenet that does not starts at 2M
6553         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
6554         [[ $nfiles == 35 ]] ||
6555                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
6556
6557         # Find files with a specified number of components
6558         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
6559         [[ $nfiles == 15 ]] ||
6560                 error "lfs find --component-count 3 - $nfiles != 15 files"
6561
6562         # Remember non-composite files have a component count of zero
6563         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
6564         [[ $nfiles == 10 ]] ||
6565                 error "lfs find --component-count 0 - $nfiles != 10 files"
6566
6567         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
6568         [[ $nfiles == 20 ]] ||
6569                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
6570
6571         # All files have a flag called "init"
6572         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
6573         [[ $nfiles == 35 ]] ||
6574                 error "lfs find --component-flags init - $nfiles != 35 files"
6575
6576         # Multi-component files will have a component not initialized
6577         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
6578         [[ $nfiles == 15 ]] ||
6579                 error "lfs find !--component-flags init - $nfiles != 15 files"
6580
6581         rm -rf $dir
6582
6583 }
6584 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
6585
6586 test_56ca() {
6587         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
6588                 skip "Need MDS version at least 2.10.57"
6589
6590         local td=$DIR/$tdir
6591         local tf=$td/$tfile
6592         local dir
6593         local nfiles
6594         local cmd
6595         local i
6596         local j
6597
6598         # create mirrored directories and mirrored files
6599         mkdir $td || error "mkdir $td failed"
6600         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
6601         createmany -o $tf- 10 || error "create $tf- failed"
6602
6603         for i in $(seq 2); do
6604                 dir=$td/dir$i
6605                 mkdir $dir || error "mkdir $dir failed"
6606                 $LFS mirror create -N$((3 + i)) $dir ||
6607                         error "create mirrored dir $dir failed"
6608                 createmany -o $dir/$tfile- 10 ||
6609                         error "create $dir/$tfile- failed"
6610         done
6611
6612         # change the states of some mirrored files
6613         echo foo > $tf-6
6614         for i in $(seq 2); do
6615                 dir=$td/dir$i
6616                 for j in $(seq 4 9); do
6617                         echo foo > $dir/$tfile-$j
6618                 done
6619         done
6620
6621         # find mirrored files with specific mirror count
6622         cmd="$LFS find --mirror-count 3 --type f $td"
6623         nfiles=$($cmd | wc -l)
6624         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
6625
6626         cmd="$LFS find ! --mirror-count 3 --type f $td"
6627         nfiles=$($cmd | wc -l)
6628         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
6629
6630         cmd="$LFS find --mirror-count +2 --type f $td"
6631         nfiles=$($cmd | wc -l)
6632         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6633
6634         cmd="$LFS find --mirror-count -6 --type f $td"
6635         nfiles=$($cmd | wc -l)
6636         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6637
6638         # find mirrored files with specific file state
6639         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
6640         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
6641
6642         cmd="$LFS find --mirror-state=ro --type f $td"
6643         nfiles=$($cmd | wc -l)
6644         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
6645
6646         cmd="$LFS find ! --mirror-state=ro --type f $td"
6647         nfiles=$($cmd | wc -l)
6648         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6649
6650         cmd="$LFS find --mirror-state=wp --type f $td"
6651         nfiles=$($cmd | wc -l)
6652         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6653
6654         cmd="$LFS find ! --mirror-state=sp --type f $td"
6655         nfiles=$($cmd | wc -l)
6656         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6657 }
6658 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
6659
6660 test_57a() {
6661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6662         # note test will not do anything if MDS is not local
6663         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6664                 skip_env "ldiskfs only test"
6665         fi
6666         remote_mds_nodsh && skip "remote MDS with nodsh"
6667
6668         local MNTDEV="osd*.*MDT*.mntdev"
6669         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
6670         [ -z "$DEV" ] && error "can't access $MNTDEV"
6671         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
6672                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
6673                         error "can't access $DEV"
6674                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
6675                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
6676                 rm $TMP/t57a.dump
6677         done
6678 }
6679 run_test 57a "verify MDS filesystem created with large inodes =="
6680
6681 test_57b() {
6682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6683         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6684                 skip_env "ldiskfs only test"
6685         fi
6686         remote_mds_nodsh && skip "remote MDS with nodsh"
6687
6688         local dir=$DIR/$tdir
6689         local filecount=100
6690         local file1=$dir/f1
6691         local fileN=$dir/f$filecount
6692
6693         rm -rf $dir || error "removing $dir"
6694         test_mkdir -c1 $dir
6695         local mdtidx=$($LFS getstripe -m $dir)
6696         local mdtname=MDT$(printf %04x $mdtidx)
6697         local facet=mds$((mdtidx + 1))
6698
6699         echo "mcreating $filecount files"
6700         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
6701
6702         # verify that files do not have EAs yet
6703         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
6704                 error "$file1 has an EA"
6705         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
6706                 error "$fileN has an EA"
6707
6708         sync
6709         sleep 1
6710         df $dir  #make sure we get new statfs data
6711         local mdsfree=$(do_facet $facet \
6712                         lctl get_param -n osd*.*$mdtname.kbytesfree)
6713         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6714         local file
6715
6716         echo "opening files to create objects/EAs"
6717         for file in $(seq -f $dir/f%g 1 $filecount); do
6718                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
6719                         error "opening $file"
6720         done
6721
6722         # verify that files have EAs now
6723         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
6724         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
6725
6726         sleep 1  #make sure we get new statfs data
6727         df $dir
6728         local mdsfree2=$(do_facet $facet \
6729                          lctl get_param -n osd*.*$mdtname.kbytesfree)
6730         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6731
6732         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
6733                 if [ "$mdsfree" != "$mdsfree2" ]; then
6734                         error "MDC before $mdcfree != after $mdcfree2"
6735                 else
6736                         echo "MDC before $mdcfree != after $mdcfree2"
6737                         echo "unable to confirm if MDS has large inodes"
6738                 fi
6739         fi
6740         rm -rf $dir
6741 }
6742 run_test 57b "default LOV EAs are stored inside large inodes ==="
6743
6744 test_58() {
6745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6746         [ -z "$(which wiretest 2>/dev/null)" ] &&
6747                         skip_env "could not find wiretest"
6748
6749         wiretest
6750 }
6751 run_test 58 "verify cross-platform wire constants =============="
6752
6753 test_59() {
6754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6755
6756         echo "touch 130 files"
6757         createmany -o $DIR/f59- 130
6758         echo "rm 130 files"
6759         unlinkmany $DIR/f59- 130
6760         sync
6761         # wait for commitment of removal
6762         wait_delete_completed
6763 }
6764 run_test 59 "verify cancellation of llog records async ========="
6765
6766 TEST60_HEAD="test_60 run $RANDOM"
6767 test_60a() {
6768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6769         remote_mgs_nodsh && skip "remote MGS with nodsh"
6770         do_facet mgs "! which run-llog.sh &> /dev/null" &&
6771                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
6772                         skip_env "missing subtest run-llog.sh"
6773
6774         log "$TEST60_HEAD - from kernel mode"
6775         do_facet mgs "$LCTL dk > /dev/null"
6776         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
6777         do_facet mgs $LCTL dk > $TMP/$tfile
6778
6779         # LU-6388: test llog_reader
6780         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
6781         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
6782         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
6783                         skip_env "missing llog_reader"
6784         local fstype=$(facet_fstype mgs)
6785         [ $fstype != ldiskfs -a $fstype != zfs ] &&
6786                 skip_env "Only for ldiskfs or zfs type mgs"
6787
6788         local mntpt=$(facet_mntpt mgs)
6789         local mgsdev=$(mgsdevname 1)
6790         local fid_list
6791         local fid
6792         local rec_list
6793         local rec
6794         local rec_type
6795         local obj_file
6796         local path
6797         local seq
6798         local oid
6799         local pass=true
6800
6801         #get fid and record list
6802         fid_list=($(awk '/9_sub.*record/ { print $NF }' /$TMP/$tfile |
6803                 tail -n 4))
6804         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' /$TMP/$tfile |
6805                 tail -n 4))
6806         #remount mgs as ldiskfs or zfs type
6807         stop mgs || error "stop mgs failed"
6808         mount_fstype mgs || error "remount mgs failed"
6809         for ((i = 0; i < ${#fid_list[@]}; i++)); do
6810                 fid=${fid_list[i]}
6811                 rec=${rec_list[i]}
6812                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
6813                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
6814                 oid=$((16#$oid))
6815
6816                 case $fstype in
6817                         ldiskfs )
6818                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
6819                         zfs )
6820                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
6821                 esac
6822                 echo "obj_file is $obj_file"
6823                 do_facet mgs $llog_reader $obj_file
6824
6825                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
6826                         awk '{ print $3 }' | sed -e "s/^type=//g")
6827                 if [ $rec_type != $rec ]; then
6828                         echo "FAILED test_60a wrong record type $rec_type," \
6829                               "should be $rec"
6830                         pass=false
6831                         break
6832                 fi
6833
6834                 #check obj path if record type is LLOG_LOGID_MAGIC
6835                 if [ "$rec" == "1064553b" ]; then
6836                         path=$(do_facet mgs $llog_reader $obj_file |
6837                                 grep "path=" | awk '{ print $NF }' |
6838                                 sed -e "s/^path=//g")
6839                         if [ $obj_file != $mntpt/$path ]; then
6840                                 echo "FAILED test_60a wrong obj path" \
6841                                       "$montpt/$path, should be $obj_file"
6842                                 pass=false
6843                                 break
6844                         fi
6845                 fi
6846         done
6847         rm -f $TMP/$tfile
6848         #restart mgs before "error", otherwise it will block the next test
6849         stop mgs || error "stop mgs failed"
6850         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
6851         $pass || error "test failed, see FAILED test_60a messages for specifics"
6852 }
6853 run_test 60a "llog_test run from kernel module and test llog_reader"
6854
6855 test_60b() { # bug 6411
6856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6857
6858         dmesg > $DIR/$tfile
6859         LLOG_COUNT=$(do_facet mgs dmesg |
6860                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
6861                           /llog_[a-z]*.c:[0-9]/ {
6862                                 if (marker)
6863                                         from_marker++
6864                                 from_begin++
6865                           }
6866                           END {
6867                                 if (marker)
6868                                         print from_marker
6869                                 else
6870                                         print from_begin
6871                           }")
6872
6873         [[ $LLOG_COUNT -gt 120 ]] &&
6874                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
6875 }
6876 run_test 60b "limit repeated messages from CERROR/CWARN"
6877
6878 test_60c() {
6879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6880
6881         echo "create 5000 files"
6882         createmany -o $DIR/f60c- 5000
6883 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
6884         lctl set_param fail_loc=0x80000137
6885         unlinkmany $DIR/f60c- 5000
6886         lctl set_param fail_loc=0
6887 }
6888 run_test 60c "unlink file when mds full"
6889
6890 test_60d() {
6891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6892
6893         SAVEPRINTK=$(lctl get_param -n printk)
6894         # verify "lctl mark" is even working"
6895         MESSAGE="test message ID $RANDOM $$"
6896         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6897         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
6898
6899         lctl set_param printk=0 || error "set lnet.printk failed"
6900         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
6901         MESSAGE="new test message ID $RANDOM $$"
6902         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
6903         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6904         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
6905
6906         lctl set_param -n printk="$SAVEPRINTK"
6907 }
6908 run_test 60d "test printk console message masking"
6909
6910 test_60e() {
6911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6912         remote_mds_nodsh && skip "remote MDS with nodsh"
6913
6914         touch $DIR/$tfile
6915 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
6916         do_facet mds1 lctl set_param fail_loc=0x15b
6917         rm $DIR/$tfile
6918 }
6919 run_test 60e "no space while new llog is being created"
6920
6921 test_60g() {
6922         local pid
6923
6924         test_mkdir -c $MDSCOUNT $DIR/$tdir
6925         $LFS setdirstripe -D -i -1 -c $MDSCOUNT $DIR/$tdir
6926
6927         (
6928                 local index=0
6929                 while true; do
6930                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
6931                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
6932                         index=$((index + 1))
6933                 done
6934         ) &
6935
6936         pid=$!
6937
6938         for i in $(seq 100); do 
6939                 # define OBD_FAIL_OSD_TXN_START    0x19a
6940                 do_facet mds1 lctl set_param fail_loc=0x8000019a
6941                 usleep 100
6942         done
6943
6944         kill -9 $pid
6945
6946         mkdir $DIR/$tdir/new || error "mkdir failed"
6947         rmdir $DIR/$tdir/new || error "rmdir failed"
6948 }
6949 run_test 60g "transaction abort won't cause MDT hung"
6950
6951 test_60h() {
6952         [ $MDS1_VERSION -le $(version_code 2.12.52) ] ||
6953                 skip "Need MDS version at least 2.12.52"
6954         [ $MDSCOUNT -le 2 ] || skip "Need >= 2 MDTs"
6955
6956         local f
6957
6958         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
6959         #define OBD_FAIL_MDS_STRIPE_FID          0x189
6960         for fail_loc in 0x80000188 0x80000189; do
6961                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
6962                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
6963                         error "mkdir $dir-$fail_loc failed"
6964                 for i in {0..10}; do
6965                         # create may fail on missing stripe
6966                         echo $i > $DIR/$tdir-$fail_loc/$i
6967                 done
6968                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
6969                         error "getdirstripe $tdir-$fail_loc failed"
6970                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
6971                         error "migrate $tdir-$fail_loc failed"
6972                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
6973                         error "getdirstripe $tdir-$fail_loc failed"
6974                 pushd $DIR/$tdir-$fail_loc
6975                 for f in *; do
6976                         echo $f | cmp $f - || error "$f data mismatch"
6977                 done
6978                 popd
6979                 rm -rf $DIR/$tdir-$fail_loc
6980         done
6981 }
6982 run_test 60h "striped directory with missing stripes can be accessed"
6983
6984 test_61a() {
6985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6986
6987         f="$DIR/f61"
6988         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
6989         cancel_lru_locks osc
6990         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
6991         sync
6992 }
6993 run_test 61a "mmap() writes don't make sync hang ================"
6994
6995 test_61b() {
6996         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
6997 }
6998 run_test 61b "mmap() of unstriped file is successful"
6999
7000 # bug 2330 - insufficient obd_match error checking causes LBUG
7001 test_62() {
7002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7003
7004         f="$DIR/f62"
7005         echo foo > $f
7006         cancel_lru_locks osc
7007         lctl set_param fail_loc=0x405
7008         cat $f && error "cat succeeded, expect -EIO"
7009         lctl set_param fail_loc=0
7010 }
7011 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7012 # match every page all of the time.
7013 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7014
7015 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7016 # Though this test is irrelevant anymore, it helped to reveal some
7017 # other grant bugs (LU-4482), let's keep it.
7018 test_63a() {   # was test_63
7019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7020
7021         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7022
7023         for i in `seq 10` ; do
7024                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7025                 sleep 5
7026                 kill $!
7027                 sleep 1
7028         done
7029
7030         rm -f $DIR/f63 || true
7031 }
7032 run_test 63a "Verify oig_wait interruption does not crash ======="
7033
7034 # bug 2248 - async write errors didn't return to application on sync
7035 # bug 3677 - async write errors left page locked
7036 test_63b() {
7037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7038
7039         debugsave
7040         lctl set_param debug=-1
7041
7042         # ensure we have a grant to do async writes
7043         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7044         rm $DIR/$tfile
7045
7046         sync    # sync lest earlier test intercept the fail_loc
7047
7048         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7049         lctl set_param fail_loc=0x80000406
7050         $MULTIOP $DIR/$tfile Owy && \
7051                 error "sync didn't return ENOMEM"
7052         sync; sleep 2; sync     # do a real sync this time to flush page
7053         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7054                 error "locked page left in cache after async error" || true
7055         debugrestore
7056 }
7057 run_test 63b "async write errors should be returned to fsync ==="
7058
7059 test_64a () {
7060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7061
7062         df $DIR
7063         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
7064 }
7065 run_test 64a "verify filter grant calculations (in kernel) ====="
7066
7067 test_64b () {
7068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7069
7070         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7071 }
7072 run_test 64b "check out-of-space detection on client"
7073
7074 test_64c() {
7075         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7076 }
7077 run_test 64c "verify grant shrink"
7078
7079 # this does exactly what osc_request.c:osc_announce_cached() does in
7080 # order to calculate max amount of grants to ask from server
7081 want_grant() {
7082         local tgt=$1
7083
7084         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
7085         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
7086
7087         ((rpc_in_flight ++));
7088         nrpages=$((nrpages * rpc_in_flight))
7089
7090         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
7091
7092         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7093
7094         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7095         local undirty=$((nrpages * PAGE_SIZE))
7096
7097         local max_extent_pages
7098         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
7099             grep grant_max_extent_size | awk '{print $2}')
7100         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7101         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7102         local grant_extent_tax
7103         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7104             grep grant_extent_tax | awk '{print $2}')
7105
7106         undirty=$((undirty + nrextents * grant_extent_tax))
7107
7108         echo $undirty
7109 }
7110
7111 # this is size of unit for grant allocation. It should be equal to
7112 # what tgt_grant.c:tgt_grant_chunk() calculates
7113 grant_chunk() {
7114         local tgt=$1
7115         local max_brw_size
7116         local grant_extent_tax
7117
7118         max_brw_size=$($LCTL get_param osc.${tgt}.import |
7119             grep max_brw_size | awk '{print $2}')
7120
7121         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7122             grep grant_extent_tax | awk '{print $2}')
7123
7124         echo $(((max_brw_size + grant_extent_tax) * 2))
7125 }
7126
7127 test_64d() {
7128         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
7129                 skip "OST < 2.10.55 doesn't limit grants enough"
7130
7131         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
7132         local file=$DIR/$tfile
7133
7134         [[ $($LCTL get_param osc.${tgt}.import |
7135              grep "connect_flags:.*grant_param") ]] ||
7136                 skip "no grant_param connect flag"
7137
7138         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
7139
7140         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
7141
7142         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7143         stack_trap "rm -f $file" EXIT
7144
7145         $LFS setstripe $file -i 0 -c 1
7146         dd if=/dev/zero of=$file bs=1M count=1000 &
7147         ddpid=$!
7148
7149         while true
7150         do
7151                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
7152                 if [[ $cur_grant -gt $max_cur_granted ]]
7153                 then
7154                         kill $ddpid
7155                         error "cur_grant $cur_grant > $max_cur_granted"
7156                 fi
7157                 kill -0 $ddpid
7158                 [[ $? -ne 0 ]] && break;
7159                 sleep 2
7160         done
7161
7162         rm -f $DIR/$tfile
7163         wait_delete_completed
7164         $LCTL set_param debug="$olddebug" 2> /dev/null || true
7165 }
7166 run_test 64d "check grant limit exceed"
7167
7168 # bug 1414 - set/get directories' stripe info
7169 test_65a() {
7170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7171
7172         test_mkdir $DIR/$tdir
7173         touch $DIR/$tdir/f1
7174         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
7175 }
7176 run_test 65a "directory with no stripe info"
7177
7178 test_65b() {
7179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7180
7181         test_mkdir $DIR/$tdir
7182         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7183
7184         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7185                                                 error "setstripe"
7186         touch $DIR/$tdir/f2
7187         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
7188 }
7189 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
7190
7191 test_65c() {
7192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7193         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
7194
7195         test_mkdir $DIR/$tdir
7196         local stripesize=$($LFS getstripe -S $DIR/$tdir)
7197
7198         $LFS setstripe -S $((stripesize * 4)) -i 1 \
7199                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
7200         touch $DIR/$tdir/f3
7201         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
7202 }
7203 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
7204
7205 test_65d() {
7206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7207
7208         test_mkdir $DIR/$tdir
7209         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
7210         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7211
7212         if [[ $STRIPECOUNT -le 0 ]]; then
7213                 sc=1
7214         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
7215                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
7216                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
7217         else
7218                 sc=$(($STRIPECOUNT - 1))
7219         fi
7220         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
7221         touch $DIR/$tdir/f4 $DIR/$tdir/f5
7222         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
7223                 error "lverify failed"
7224 }
7225 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
7226
7227 test_65e() {
7228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7229
7230         test_mkdir $DIR/$tdir
7231
7232         $LFS setstripe $DIR/$tdir || error "setstripe"
7233         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7234                                         error "no stripe info failed"
7235         touch $DIR/$tdir/f6
7236         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
7237 }
7238 run_test 65e "directory setstripe defaults"
7239
7240 test_65f() {
7241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7242
7243         test_mkdir $DIR/${tdir}f
7244         $RUNAS $LFS setstripe $DIR/${tdir}f &&
7245                 error "setstripe succeeded" || true
7246 }
7247 run_test 65f "dir setstripe permission (should return error) ==="
7248
7249 test_65g() {
7250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7251
7252         test_mkdir $DIR/$tdir
7253         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7254
7255         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7256                 error "setstripe -S failed"
7257         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
7258         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7259                 error "delete default stripe failed"
7260 }
7261 run_test 65g "directory setstripe -d"
7262
7263 test_65h() {
7264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7265
7266         test_mkdir $DIR/$tdir
7267         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7268
7269         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7270                 error "setstripe -S failed"
7271         test_mkdir $DIR/$tdir/dd1
7272         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
7273                 error "stripe info inherit failed"
7274 }
7275 run_test 65h "directory stripe info inherit ===================="
7276
7277 test_65i() {
7278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7279
7280         save_layout_restore_at_exit $MOUNT
7281
7282         # bug6367: set non-default striping on root directory
7283         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
7284
7285         # bug12836: getstripe on -1 default directory striping
7286         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
7287
7288         # bug12836: getstripe -v on -1 default directory striping
7289         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
7290
7291         # bug12836: new find on -1 default directory striping
7292         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
7293 }
7294 run_test 65i "various tests to set root directory striping"
7295
7296 test_65j() { # bug6367
7297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7298
7299         sync; sleep 1
7300
7301         # if we aren't already remounting for each test, do so for this test
7302         if [ "$CLEANUP" = ":" -a "$I_MOUNTED" = "yes" ]; then
7303                 cleanup || error "failed to unmount"
7304                 setup
7305         fi
7306
7307         save_layout_restore_at_exit $MOUNT
7308
7309         $LFS setstripe -d $MOUNT || error "setstripe failed"
7310 }
7311 run_test 65j "set default striping on root directory (bug 6367)="
7312
7313 cleanup_65k() {
7314         rm -rf $DIR/$tdir
7315         wait_delete_completed
7316         do_facet $SINGLEMDS "lctl set_param -n \
7317                 osp.$ost*MDT0000.max_create_count=$max_count"
7318         do_facet $SINGLEMDS "lctl set_param -n \
7319                 osp.$ost*MDT0000.create_count=$count"
7320         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7321         echo $INACTIVE_OSC "is Activate"
7322
7323         wait_osc_import_state mds ost$ostnum FULL
7324 }
7325
7326 test_65k() { # bug11679
7327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7328         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7329         remote_mds_nodsh && skip "remote MDS with nodsh"
7330
7331         local disable_precreate=true
7332         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
7333                 disable_precreate=false
7334
7335         echo "Check OST status: "
7336         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
7337                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
7338
7339         for OSC in $MDS_OSCS; do
7340                 echo $OSC "is active"
7341                 do_facet $SINGLEMDS lctl --device %$OSC activate
7342         done
7343
7344         for INACTIVE_OSC in $MDS_OSCS; do
7345                 local ost=$(osc_to_ost $INACTIVE_OSC)
7346                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
7347                                lov.*md*.target_obd |
7348                                awk -F: /$ost/'{ print $1 }' | head -n 1)
7349
7350                 mkdir -p $DIR/$tdir
7351                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
7352                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
7353
7354                 echo "Deactivate: " $INACTIVE_OSC
7355                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
7356
7357                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
7358                               osp.$ost*MDT0000.create_count")
7359                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
7360                                   osp.$ost*MDT0000.max_create_count")
7361                 $disable_precreate &&
7362                         do_facet $SINGLEMDS "lctl set_param -n \
7363                                 osp.$ost*MDT0000.max_create_count=0"
7364
7365                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
7366                         [ -f $DIR/$tdir/$idx ] && continue
7367                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
7368                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
7369                                 { cleanup_65k;
7370                                   error "setstripe $idx should succeed"; }
7371                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
7372                 done
7373                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
7374                 rmdir $DIR/$tdir
7375
7376                 do_facet $SINGLEMDS "lctl set_param -n \
7377                         osp.$ost*MDT0000.max_create_count=$max_count"
7378                 do_facet $SINGLEMDS "lctl set_param -n \
7379                         osp.$ost*MDT0000.create_count=$count"
7380                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7381                 echo $INACTIVE_OSC "is Activate"
7382
7383                 wait_osc_import_state mds ost$ostnum FULL
7384         done
7385 }
7386 run_test 65k "validate manual striping works properly with deactivated OSCs"
7387
7388 test_65l() { # bug 12836
7389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7390
7391         test_mkdir -p $DIR/$tdir/test_dir
7392         $LFS setstripe -c -1 $DIR/$tdir/test_dir
7393         $LFS find -mtime -1 $DIR/$tdir >/dev/null
7394 }
7395 run_test 65l "lfs find on -1 stripe dir ========================"
7396
7397 test_65m() {
7398         local layout=$(save_layout $MOUNT)
7399         $RUNAS $LFS setstripe -c 2 $MOUNT && {
7400                 restore_layout $MOUNT $layout
7401                 error "setstripe should fail by non-root users"
7402         }
7403         true
7404 }
7405 run_test 65m "normal user can't set filesystem default stripe"
7406
7407 test_65n() {
7408         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
7409         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.12.50) ]] ||
7410                 skip "Need MDS version at least 2.12.50"
7411         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7412
7413         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7414         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
7415         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
7416
7417         local root_layout=$(save_layout $MOUNT)
7418         stack_trap "restore_layout $MOUNT $root_layout" EXIT
7419
7420         # new subdirectory under root directory should not inherit
7421         # the default layout from root
7422         local dir1=$MOUNT/$tdir-1
7423         mkdir $dir1 || error "mkdir $dir1 failed"
7424         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
7425                 error "$dir1 shouldn't have LOV EA"
7426
7427         # delete the default layout on root directory
7428         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
7429
7430         local dir2=$MOUNT/$tdir-2
7431         mkdir $dir2 || error "mkdir $dir2 failed"
7432         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
7433                 error "$dir2 shouldn't have LOV EA"
7434
7435         # set a new striping pattern on root directory
7436         local def_stripe_size=$($LFS getstripe -S $MOUNT)
7437         local new_def_stripe_size=$((def_stripe_size * 2))
7438         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
7439                 error "set stripe size on $MOUNT failed"
7440
7441         # new file created in $dir2 should inherit the new stripe size from
7442         # the filesystem default
7443         local file2=$dir2/$tfile-2
7444         touch $file2 || error "touch $file2 failed"
7445
7446         local file2_stripe_size=$($LFS getstripe -S $file2)
7447         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
7448                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
7449
7450         local dir3=$MOUNT/$tdir-3
7451         mkdir $dir3 || error "mkdir $dir3 failed"
7452         ! getfattr -n trusted.lov $dir3 &> /dev/null ||
7453                 error "$dir3 shouldn't have LOV EA"
7454
7455         # set OST pool on root directory
7456         local pool=$TESTNAME
7457         pool_add $pool || error "add $pool failed"
7458         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
7459                 error "add targets to $pool failed"
7460
7461         $LFS setstripe -p $pool $MOUNT ||
7462                 error "set OST pool on $MOUNT failed"
7463
7464         # new file created in $dir3 should inherit the pool from
7465         # the filesystem default
7466         local file3=$dir3/$tfile-3
7467         touch $file3 || error "touch $file3 failed"
7468
7469         local file3_pool=$($LFS getstripe -p $file3)
7470         [[ "$file3_pool" = "$pool" ]] ||
7471                 error "$file3 didn't inherit OST pool $pool"
7472
7473         local dir4=$MOUNT/$tdir-4
7474         mkdir $dir4 || error "mkdir $dir4 failed"
7475         ! getfattr -n trusted.lov $dir4 &> /dev/null ||
7476                 error "$dir4 shouldn't have LOV EA"
7477
7478         # new file created in $dir4 should inherit the pool from
7479         # the filesystem default
7480         local file4=$dir4/$tfile-4
7481         touch $file4 || error "touch $file4 failed"
7482
7483         local file4_pool=$($LFS getstripe -p $file4)
7484         [[ "$file4_pool" = "$pool" ]] ||
7485                 error "$file4 didn't inherit OST pool $pool"
7486
7487         # new subdirectory under non-root directory should inherit
7488         # the default layout from its parent directory
7489         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
7490                 error "set directory layout on $dir4 failed"
7491
7492         local dir5=$dir4/$tdir-5
7493         mkdir $dir5 || error "mkdir $dir5 failed"
7494
7495         local dir4_layout=$(get_layout_param $dir4)
7496         local dir5_layout=$(get_layout_param $dir5)
7497         [[ "$dir4_layout" = "$dir5_layout" ]] ||
7498                 error "$dir5 should inherit the default layout from $dir4"
7499 }
7500 run_test 65n "don't inherit default layout from root for new subdirectories"
7501
7502 # bug 2543 - update blocks count on client
7503 test_66() {
7504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7505
7506         COUNT=${COUNT:-8}
7507         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
7508         sync; sync_all_data; sync; sync_all_data
7509         cancel_lru_locks osc
7510         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
7511         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
7512 }
7513 run_test 66 "update inode blocks count on client ==============="
7514
7515 meminfo() {
7516         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
7517 }
7518
7519 swap_used() {
7520         swapon -s | awk '($1 == "'$1'") { print $4 }'
7521 }
7522
7523 # bug5265, obdfilter oa2dentry return -ENOENT
7524 # #define OBD_FAIL_SRV_ENOENT 0x217
7525 test_69() {
7526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7527         remote_ost_nodsh && skip "remote OST with nodsh"
7528
7529         f="$DIR/$tfile"
7530         $LFS setstripe -c 1 -i 0 $f
7531
7532         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
7533
7534         do_facet ost1 lctl set_param fail_loc=0x217
7535         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
7536         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
7537
7538         do_facet ost1 lctl set_param fail_loc=0
7539         $DIRECTIO write $f 0 2 || error "write error"
7540
7541         cancel_lru_locks osc
7542         $DIRECTIO read $f 0 1 || error "read error"
7543
7544         do_facet ost1 lctl set_param fail_loc=0x217
7545         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
7546
7547         do_facet ost1 lctl set_param fail_loc=0
7548         rm -f $f
7549 }
7550 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
7551
7552 test_71() {
7553         test_mkdir $DIR/$tdir
7554         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
7555         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
7556 }
7557 run_test 71 "Running dbench on lustre (don't segment fault) ===="
7558
7559 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
7560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7561         [ "$RUNAS_ID" = "$UID" ] &&
7562                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7563         # Check that testing environment is properly set up. Skip if not
7564         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
7565                 skip_env "User $RUNAS_ID does not exist - skipping"
7566
7567         touch $DIR/$tfile
7568         chmod 777 $DIR/$tfile
7569         chmod ug+s $DIR/$tfile
7570         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
7571                 error "$RUNAS dd $DIR/$tfile failed"
7572         # See if we are still setuid/sgid
7573         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7574                 error "S/gid is not dropped on write"
7575         # Now test that MDS is updated too
7576         cancel_lru_locks mdc
7577         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7578                 error "S/gid is not dropped on MDS"
7579         rm -f $DIR/$tfile
7580 }
7581 run_test 72a "Test that remove suid works properly (bug5695) ===="
7582
7583 test_72b() { # bug 24226 -- keep mode setting when size is not changing
7584         local perm
7585
7586         [ "$RUNAS_ID" = "$UID" ] &&
7587                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7588         [ "$RUNAS_ID" -eq 0 ] &&
7589                 skip_env "RUNAS_ID = 0 -- skipping"
7590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7591         # Check that testing environment is properly set up. Skip if not
7592         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
7593                 skip_env "User $RUNAS_ID does not exist - skipping"
7594
7595         touch $DIR/${tfile}-f{g,u}
7596         test_mkdir $DIR/${tfile}-dg
7597         test_mkdir $DIR/${tfile}-du
7598         chmod 770 $DIR/${tfile}-{f,d}{g,u}
7599         chmod g+s $DIR/${tfile}-{f,d}g
7600         chmod u+s $DIR/${tfile}-{f,d}u
7601         for perm in 777 2777 4777; do
7602                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
7603                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
7604                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
7605                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
7606         done
7607         true
7608 }
7609 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
7610
7611 # bug 3462 - multiple simultaneous MDC requests
7612 test_73() {
7613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7614
7615         test_mkdir $DIR/d73-1
7616         test_mkdir $DIR/d73-2
7617         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
7618         pid1=$!
7619
7620         lctl set_param fail_loc=0x80000129
7621         $MULTIOP $DIR/d73-1/f73-2 Oc &
7622         sleep 1
7623         lctl set_param fail_loc=0
7624
7625         $MULTIOP $DIR/d73-2/f73-3 Oc &
7626         pid3=$!
7627
7628         kill -USR1 $pid1
7629         wait $pid1 || return 1
7630
7631         sleep 25
7632
7633         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
7634         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
7635         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
7636
7637         rm -rf $DIR/d73-*
7638 }
7639 run_test 73 "multiple MDC requests (should not deadlock)"
7640
7641 test_74a() { # bug 6149, 6184
7642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7643
7644         touch $DIR/f74a
7645         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7646         #
7647         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7648         # will spin in a tight reconnection loop
7649         $LCTL set_param fail_loc=0x8000030e
7650         # get any lock that won't be difficult - lookup works.
7651         ls $DIR/f74a
7652         $LCTL set_param fail_loc=0
7653         rm -f $DIR/f74a
7654         true
7655 }
7656 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
7657
7658 test_74b() { # bug 13310
7659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7660
7661         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7662         #
7663         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7664         # will spin in a tight reconnection loop
7665         $LCTL set_param fail_loc=0x8000030e
7666         # get a "difficult" lock
7667         touch $DIR/f74b
7668         $LCTL set_param fail_loc=0
7669         rm -f $DIR/f74b
7670         true
7671 }
7672 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
7673
7674 test_74c() {
7675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7676
7677         #define OBD_FAIL_LDLM_NEW_LOCK
7678         $LCTL set_param fail_loc=0x319
7679         touch $DIR/$tfile && error "touch successful"
7680         $LCTL set_param fail_loc=0
7681         true
7682 }
7683 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
7684
7685 num_inodes() {
7686         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
7687 }
7688
7689 test_76() { # Now for bug 20433, added originally in bug 1443
7690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7691
7692         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
7693
7694         cancel_lru_locks osc
7695         BEFORE_INODES=$(num_inodes)
7696         echo "before inodes: $BEFORE_INODES"
7697         local COUNT=1000
7698         [ "$SLOW" = "no" ] && COUNT=100
7699         for i in $(seq $COUNT); do
7700                 touch $DIR/$tfile
7701                 rm -f $DIR/$tfile
7702         done
7703         cancel_lru_locks osc
7704         AFTER_INODES=$(num_inodes)
7705         echo "after inodes: $AFTER_INODES"
7706         local wait=0
7707         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
7708                 sleep 2
7709                 AFTER_INODES=$(num_inodes)
7710                 wait=$((wait+2))
7711                 echo "wait $wait seconds inodes: $AFTER_INODES"
7712                 if [ $wait -gt 30 ]; then
7713                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
7714                 fi
7715         done
7716 }
7717 run_test 76 "confirm clients recycle inodes properly ===="
7718
7719
7720 export ORIG_CSUM=""
7721 set_checksums()
7722 {
7723         # Note: in sptlrpc modes which enable its own bulk checksum, the
7724         # original crc32_le bulk checksum will be automatically disabled,
7725         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
7726         # will be checked by sptlrpc code against sptlrpc bulk checksum.
7727         # In this case set_checksums() will not be no-op, because sptlrpc
7728         # bulk checksum will be enabled all through the test.
7729
7730         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
7731         lctl set_param -n osc.*.checksums $1
7732         return 0
7733 }
7734
7735 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7736                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
7737 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7738                              tr -d [] | head -n1)}
7739 set_checksum_type()
7740 {
7741         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
7742         log "set checksum type to $1"
7743         return 0
7744 }
7745 F77_TMP=$TMP/f77-temp
7746 F77SZ=8
7747 setup_f77() {
7748         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
7749                 error "error writing to $F77_TMP"
7750 }
7751
7752 test_77a() { # bug 10889
7753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7754         $GSS && skip_env "could not run with gss"
7755
7756         [ ! -f $F77_TMP ] && setup_f77
7757         set_checksums 1
7758         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
7759         set_checksums 0
7760         rm -f $DIR/$tfile
7761 }
7762 run_test 77a "normal checksum read/write operation"
7763
7764 test_77b() { # bug 10889
7765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7766         $GSS && skip_env "could not run with gss"
7767
7768         [ ! -f $F77_TMP ] && setup_f77
7769         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7770         $LCTL set_param fail_loc=0x80000409
7771         set_checksums 1
7772
7773         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7774                 error "dd error: $?"
7775         $LCTL set_param fail_loc=0
7776
7777         for algo in $CKSUM_TYPES; do
7778                 cancel_lru_locks osc
7779                 set_checksum_type $algo
7780                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7781                 $LCTL set_param fail_loc=0x80000408
7782                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
7783                 $LCTL set_param fail_loc=0
7784         done
7785         set_checksums 0
7786         set_checksum_type $ORIG_CSUM_TYPE
7787         rm -f $DIR/$tfile
7788 }
7789 run_test 77b "checksum error on client write, read"
7790
7791 cleanup_77c() {
7792         trap 0
7793         set_checksums 0
7794         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
7795         $check_ost &&
7796                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
7797         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
7798         $check_ost && [ -n "$ost_file_prefix" ] &&
7799                 do_facet ost1 rm -f ${ost_file_prefix}\*
7800 }
7801
7802 test_77c() {
7803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7804         $GSS && skip_env "could not run with gss"
7805         remote_ost_nodsh && skip "remote OST with nodsh"
7806
7807         local bad1
7808         local osc_file_prefix
7809         local osc_file
7810         local check_ost=false
7811         local ost_file_prefix
7812         local ost_file
7813         local orig_cksum
7814         local dump_cksum
7815         local fid
7816
7817         # ensure corruption will occur on first OSS/OST
7818         $LFS setstripe -i 0 $DIR/$tfile
7819
7820         [ ! -f $F77_TMP ] && setup_f77
7821         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7822                 error "dd write error: $?"
7823         fid=$($LFS path2fid $DIR/$tfile)
7824
7825         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
7826         then
7827                 check_ost=true
7828                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
7829                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
7830         else
7831                 echo "OSS do not support bulk pages dump upon error"
7832         fi
7833
7834         osc_file_prefix=$($LCTL get_param -n debug_path)
7835         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
7836
7837         trap cleanup_77c EXIT
7838
7839         set_checksums 1
7840         # enable bulk pages dump upon error on Client
7841         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
7842         # enable bulk pages dump upon error on OSS
7843         $check_ost &&
7844                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
7845
7846         # flush Client cache to allow next read to reach OSS
7847         cancel_lru_locks osc
7848
7849         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
7850         $LCTL set_param fail_loc=0x80000408
7851         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
7852         $LCTL set_param fail_loc=0
7853
7854         rm -f $DIR/$tfile
7855
7856         # check cksum dump on Client
7857         osc_file=$(ls ${osc_file_prefix}*)
7858         [ -n "$osc_file" ] || error "no checksum dump file on Client"
7859         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
7860         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
7861         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
7862         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
7863                      cksum)
7864         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
7865         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7866                 error "dump content does not match on Client"
7867
7868         $check_ost || skip "No need to check cksum dump on OSS"
7869
7870         # check cksum dump on OSS
7871         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
7872         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
7873         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
7874         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
7875         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7876                 error "dump content does not match on OSS"
7877
7878         cleanup_77c
7879 }
7880 run_test 77c "checksum error on client read with debug"
7881
7882 test_77d() { # bug 10889
7883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7884         $GSS && skip_env "could not run with gss"
7885
7886         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7887         $LCTL set_param fail_loc=0x80000409
7888         set_checksums 1
7889         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7890                 error "direct write: rc=$?"
7891         $LCTL set_param fail_loc=0
7892         set_checksums 0
7893
7894         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7895         $LCTL set_param fail_loc=0x80000408
7896         set_checksums 1
7897         cancel_lru_locks osc
7898         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7899                 error "direct read: rc=$?"
7900         $LCTL set_param fail_loc=0
7901         set_checksums 0
7902 }
7903 run_test 77d "checksum error on OST direct write, read"
7904
7905 test_77f() { # bug 10889
7906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7907         $GSS && skip_env "could not run with gss"
7908
7909         set_checksums 1
7910         for algo in $CKSUM_TYPES; do
7911                 cancel_lru_locks osc
7912                 set_checksum_type $algo
7913                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7914                 $LCTL set_param fail_loc=0x409
7915                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
7916                         error "direct write succeeded"
7917                 $LCTL set_param fail_loc=0
7918         done
7919         set_checksum_type $ORIG_CSUM_TYPE
7920         set_checksums 0
7921 }
7922 run_test 77f "repeat checksum error on write (expect error)"
7923
7924 test_77g() { # bug 10889
7925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7926         $GSS && skip_env "could not run with gss"
7927         remote_ost_nodsh && skip "remote OST with nodsh"
7928
7929         [ ! -f $F77_TMP ] && setup_f77
7930
7931         local file=$DIR/$tfile
7932         stack_trap "rm -f $file" EXIT
7933
7934         $LFS setstripe -c 1 -i 0 $file
7935         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
7936         do_facet ost1 lctl set_param fail_loc=0x8000021a
7937         set_checksums 1
7938         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
7939                 error "write error: rc=$?"
7940         do_facet ost1 lctl set_param fail_loc=0
7941         set_checksums 0
7942
7943         cancel_lru_locks osc
7944         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
7945         do_facet ost1 lctl set_param fail_loc=0x8000021b
7946         set_checksums 1
7947         cmp $F77_TMP $file || error "file compare failed"
7948         do_facet ost1 lctl set_param fail_loc=0
7949         set_checksums 0
7950 }
7951 run_test 77g "checksum error on OST write, read"
7952
7953 test_77k() { # LU-10906
7954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7955         $GSS && skip_env "could not run with gss"
7956
7957         local cksum_param="osc.$FSNAME*.checksums"
7958         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
7959         local checksum
7960         local i
7961
7962         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
7963         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
7964         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
7965                 EXIT
7966
7967         for i in 0 1; do
7968                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
7969                         error "failed to set checksum=$i on MGS"
7970                 wait_update $HOSTNAME "$get_checksum" $i
7971                 #remount
7972                 echo "remount client, checksum should be $i"
7973                 remount_client $MOUNT || "failed to remount client"
7974                 checksum=$(eval $get_checksum)
7975                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7976         done
7977         # remove persistent param to avoid races with checksum mountopt below
7978         do_facet mgs $LCTL set_param -P -d $cksum_param ||
7979                 error "failed to delete checksum on MGS"
7980
7981         for opt in "checksum" "nochecksum"; do
7982                 #remount with mount option
7983                 echo "remount client with option $opt, checksum should be $i"
7984                 umount_client $MOUNT || "failed to umount client"
7985                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
7986                         "failed to mount client with option '$opt'"
7987                 checksum=$(eval $get_checksum)
7988                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7989                 i=$((i - 1))
7990         done
7991
7992         remount_client $MOUNT || "failed to remount client"
7993 }
7994 run_test 77k "enable/disable checksum correctly"
7995
7996 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
7997 rm -f $F77_TMP
7998 unset F77_TMP
7999
8000 cleanup_test_78() {
8001         trap 0
8002         rm -f $DIR/$tfile
8003 }
8004
8005 test_78() { # bug 10901
8006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8007         remote_ost || skip_env "local OST"
8008
8009         NSEQ=5
8010         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
8011         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
8012         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
8013         echo "MemTotal: $MEMTOTAL"
8014
8015         # reserve 256MB of memory for the kernel and other running processes,
8016         # and then take 1/2 of the remaining memory for the read/write buffers.
8017         if [ $MEMTOTAL -gt 512 ] ;then
8018                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
8019         else
8020                 # for those poor memory-starved high-end clusters...
8021                 MEMTOTAL=$((MEMTOTAL / 2))
8022         fi
8023         echo "Mem to use for directio: $MEMTOTAL"
8024
8025         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
8026         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
8027         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
8028         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
8029                 head -n1)
8030         echo "Smallest OST: $SMALLESTOST"
8031         [[ $SMALLESTOST -lt 10240 ]] &&
8032                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
8033
8034         trap cleanup_test_78 EXIT
8035
8036         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
8037                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
8038
8039         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
8040         echo "File size: $F78SIZE"
8041         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
8042         for i in $(seq 1 $NSEQ); do
8043                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
8044                 echo directIO rdwr round $i of $NSEQ
8045                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
8046         done
8047
8048         cleanup_test_78
8049 }
8050 run_test 78 "handle large O_DIRECT writes correctly ============"
8051
8052 test_79() { # bug 12743
8053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8054
8055         wait_delete_completed
8056
8057         BKTOTAL=$(calc_osc_kbytes kbytestotal)
8058         BKFREE=$(calc_osc_kbytes kbytesfree)
8059         BKAVAIL=$(calc_osc_kbytes kbytesavail)
8060
8061         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
8062         DFTOTAL=`echo $STRING | cut -d, -f1`
8063         DFUSED=`echo $STRING  | cut -d, -f2`
8064         DFAVAIL=`echo $STRING | cut -d, -f3`
8065         DFFREE=$(($DFTOTAL - $DFUSED))
8066
8067         ALLOWANCE=$((64 * $OSTCOUNT))
8068
8069         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
8070            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
8071                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
8072         fi
8073         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
8074            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
8075                 error "df free($DFFREE) mismatch OST free($BKFREE)"
8076         fi
8077         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
8078            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
8079                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
8080         fi
8081 }
8082 run_test 79 "df report consistency check ======================="
8083
8084 test_80() { # bug 10718
8085         remote_ost_nodsh && skip "remote OST with nodsh"
8086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8087
8088         # relax strong synchronous semantics for slow backends like ZFS
8089         local soc="obdfilter.*.sync_on_lock_cancel"
8090         local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
8091         local hosts=
8092         if [ "$soc_old" != "never" ] &&
8093                 [ "$ost1_FSTYPE" != "ldiskfs" ]; then
8094                         hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
8095                                 facet_active_host $host; done | sort -u)
8096                         do_nodes $hosts lctl set_param $soc=never
8097         fi
8098
8099         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
8100         sync; sleep 1; sync
8101         local BEFORE=`date +%s`
8102         cancel_lru_locks osc
8103         local AFTER=`date +%s`
8104         local DIFF=$((AFTER-BEFORE))
8105         if [ $DIFF -gt 1 ] ; then
8106                 error "elapsed for 1M@1T = $DIFF"
8107         fi
8108
8109         [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
8110
8111         rm -f $DIR/$tfile
8112 }
8113 run_test 80 "Page eviction is equally fast at high offsets too  ===="
8114
8115 test_81a() { # LU-456
8116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8117         remote_ost_nodsh && skip "remote OST with nodsh"
8118
8119         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8120         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
8121         do_facet ost1 lctl set_param fail_loc=0x80000228
8122
8123         # write should trigger a retry and success
8124         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8125         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8126         RC=$?
8127         if [ $RC -ne 0 ] ; then
8128                 error "write should success, but failed for $RC"
8129         fi
8130 }
8131 run_test 81a "OST should retry write when get -ENOSPC ==============="
8132
8133 test_81b() { # LU-456
8134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8135         remote_ost_nodsh && skip "remote OST with nodsh"
8136
8137         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8138         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
8139         do_facet ost1 lctl set_param fail_loc=0x228
8140
8141         # write should retry several times and return -ENOSPC finally
8142         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8143         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8144         RC=$?
8145         ENOSPC=28
8146         if [ $RC -ne $ENOSPC ] ; then
8147                 error "dd should fail for -ENOSPC, but succeed."
8148         fi
8149 }
8150 run_test 81b "OST should return -ENOSPC when retry still fails ======="
8151
8152 test_82() { # LU-1031
8153         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
8154         local gid1=14091995
8155         local gid2=16022000
8156
8157         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
8158         local MULTIPID1=$!
8159         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
8160         local MULTIPID2=$!
8161         kill -USR1 $MULTIPID2
8162         sleep 2
8163         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
8164                 error "First grouplock does not block second one"
8165         else
8166                 echo "Second grouplock blocks first one"
8167         fi
8168         kill -USR1 $MULTIPID1
8169         wait $MULTIPID1
8170         wait $MULTIPID2
8171 }
8172 run_test 82 "Basic grouplock test"
8173
8174 test_99() {
8175         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
8176
8177         test_mkdir $DIR/$tdir.cvsroot
8178         chown $RUNAS_ID $DIR/$tdir.cvsroot
8179
8180         cd $TMP
8181         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
8182
8183         cd /etc/init.d
8184         # some versions of cvs import exit(1) when asked to import links or
8185         # files they can't read.  ignore those files.
8186         local toignore=$(find . -type l -printf '-I %f\n' -o \
8187                          ! -perm /4 -printf '-I %f\n')
8188         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
8189                 $tdir.reposname vtag rtag
8190
8191         cd $DIR
8192         test_mkdir $DIR/$tdir.reposname
8193         chown $RUNAS_ID $DIR/$tdir.reposname
8194         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
8195
8196         cd $DIR/$tdir.reposname
8197         $RUNAS touch foo99
8198         $RUNAS cvs add -m 'addmsg' foo99
8199         $RUNAS cvs update
8200         $RUNAS cvs commit -m 'nomsg' foo99
8201         rm -fr $DIR/$tdir.cvsroot
8202 }
8203 run_test 99 "cvs strange file/directory operations"
8204
8205 test_100() {
8206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8207         [[ "$NETTYPE" =~ tcp ]] ||
8208                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
8209         remote_ost_nodsh && skip "remote OST with nodsh"
8210         remote_mds_nodsh && skip "remote MDS with nodsh"
8211         remote_servers ||
8212                 skip "useless for local single node setup"
8213
8214         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
8215                 [ "$PROT" != "tcp" ] && continue
8216                 RPORT=$(echo $REMOTE | cut -d: -f2)
8217                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
8218
8219                 rc=0
8220                 LPORT=`echo $LOCAL | cut -d: -f2`
8221                 if [ $LPORT -ge 1024 ]; then
8222                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
8223                         netstat -tna
8224                         error_exit "local: $LPORT > 1024, remote: $RPORT"
8225                 fi
8226         done
8227         [ "$rc" = 0 ] || error_exit "privileged port not found" )
8228 }
8229 run_test 100 "check local port using privileged port ==========="
8230
8231 function get_named_value()
8232 {
8233     local tag
8234
8235     tag=$1
8236     while read ;do
8237         line=$REPLY
8238         case $line in
8239         $tag*)
8240             echo $line | sed "s/^$tag[ ]*//"
8241             break
8242             ;;
8243         esac
8244     done
8245 }
8246
8247 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
8248                    awk '/^max_cached_mb/ { print $2 }')
8249
8250 cleanup_101a() {
8251         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
8252         trap 0
8253 }
8254
8255 test_101a() {
8256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8257         [ $MDSCOUNT -ge 2 ] && skip_env "needs < 2 MDTs" #LU-4322
8258
8259         local s
8260         local discard
8261         local nreads=10000
8262         local cache_limit=32
8263
8264         $LCTL set_param -n osc.*-osc*.rpc_stats 0
8265         trap cleanup_101a EXIT
8266         $LCTL set_param -n llite.*.read_ahead_stats 0
8267         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
8268
8269         #
8270         # randomly read 10000 of 64K chunks from file 3x 32MB in size
8271         #
8272         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
8273         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
8274
8275         discard=0
8276         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
8277                 get_named_value 'read but discarded' | cut -d" " -f1); do
8278                         discard=$(($discard + $s))
8279         done
8280         cleanup_101a
8281
8282         if [[ $(($discard * 10)) -gt $nreads ]]; then
8283                 $LCTL get_param osc.*-osc*.rpc_stats
8284                 $LCTL get_param llite.*.read_ahead_stats
8285                 error "too many ($discard) discarded pages"
8286         fi
8287         rm -f $DIR/$tfile || true
8288 }
8289 run_test 101a "check read-ahead for random reads"
8290
8291 setup_test101bc() {
8292         test_mkdir $DIR/$tdir
8293         local ssize=$1
8294         local FILE_LENGTH=$2
8295         STRIPE_OFFSET=0
8296
8297         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
8298
8299         local list=$(comma_list $(osts_nodes))
8300         set_osd_param $list '' read_cache_enable 0
8301         set_osd_param $list '' writethrough_cache_enable 0
8302
8303         trap cleanup_test101bc EXIT
8304         # prepare the read-ahead file
8305         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
8306
8307         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
8308                                 count=$FILE_SIZE_MB 2> /dev/null
8309
8310 }
8311
8312 cleanup_test101bc() {
8313         trap 0
8314         rm -rf $DIR/$tdir
8315         rm -f $DIR/$tfile
8316
8317         local list=$(comma_list $(osts_nodes))
8318         set_osd_param $list '' read_cache_enable 1
8319         set_osd_param $list '' writethrough_cache_enable 1
8320 }
8321
8322 calc_total() {
8323         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
8324 }
8325
8326 ra_check_101() {
8327         local READ_SIZE=$1
8328         local STRIPE_SIZE=$2
8329         local FILE_LENGTH=$3
8330         local RA_INC=1048576
8331         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
8332         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
8333                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
8334         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
8335                         get_named_value 'read but discarded' |
8336                         cut -d" " -f1 | calc_total)
8337         if [[ $DISCARD -gt $discard_limit ]]; then
8338                 $LCTL get_param llite.*.read_ahead_stats
8339                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
8340         else
8341                 echo "Read-ahead success for size ${READ_SIZE}"
8342         fi
8343 }
8344
8345 test_101b() {
8346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8347         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8348
8349         local STRIPE_SIZE=1048576
8350         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
8351
8352         if [ $SLOW == "yes" ]; then
8353                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
8354         else
8355                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
8356         fi
8357
8358         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
8359
8360         # prepare the read-ahead file
8361         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8362         cancel_lru_locks osc
8363         for BIDX in 2 4 8 16 32 64 128 256
8364         do
8365                 local BSIZE=$((BIDX*4096))
8366                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
8367                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
8368                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
8369                 $LCTL set_param -n llite.*.read_ahead_stats 0
8370                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
8371                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
8372                 cancel_lru_locks osc
8373                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
8374         done
8375         cleanup_test101bc
8376         true
8377 }
8378 run_test 101b "check stride-io mode read-ahead ================="
8379
8380 test_101c() {
8381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8382
8383         local STRIPE_SIZE=1048576
8384         local FILE_LENGTH=$((STRIPE_SIZE*100))
8385         local nreads=10000
8386         local rsize=65536
8387         local osc_rpc_stats
8388
8389         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8390
8391         cancel_lru_locks osc
8392         $LCTL set_param osc.*.rpc_stats 0
8393         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
8394         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
8395                 local stats=$($LCTL get_param -n $osc_rpc_stats)
8396                 local lines=$(echo "$stats" | awk 'END {print NR;}')
8397                 local size
8398
8399                 if [ $lines -le 20 ]; then
8400                         continue
8401                 fi
8402                 for size in 1 2 4 8; do
8403                         local rpc=$(echo "$stats" |
8404                                     awk '($1 == "'$size':") {print $2; exit; }')
8405                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
8406                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
8407                 done
8408                 echo "$osc_rpc_stats check passed!"
8409         done
8410         cleanup_test101bc
8411         true
8412 }
8413 run_test 101c "check stripe_size aligned read-ahead ================="
8414
8415 set_read_ahead() {
8416         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
8417         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
8418 }
8419
8420 test_101d() {
8421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8422
8423         local file=$DIR/$tfile
8424         local sz_MB=${FILESIZE_101d:-500}
8425         local ra_MB=${READAHEAD_MB:-40}
8426
8427         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
8428         [ $free_MB -lt $sz_MB ] &&
8429                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
8430
8431         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
8432         $LFS setstripe -c -1 $file || error "setstripe failed"
8433
8434         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
8435         echo Cancel LRU locks on lustre client to flush the client cache
8436         cancel_lru_locks osc
8437
8438         echo Disable read-ahead
8439         local old_READAHEAD=$(set_read_ahead 0)
8440
8441         echo Reading the test file $file with read-ahead disabled
8442         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8443
8444         echo Cancel LRU locks on lustre client to flush the client cache
8445         cancel_lru_locks osc
8446         echo Enable read-ahead with ${ra_MB}MB
8447         set_read_ahead $ra_MB
8448
8449         echo Reading the test file $file with read-ahead enabled
8450         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8451
8452         echo "read-ahead disabled time read $raOFF"
8453         echo "read-ahead enabled  time read $raON"
8454
8455         set_read_ahead $old_READAHEAD
8456         rm -f $file
8457         wait_delete_completed
8458
8459         [ $raOFF -le 1 ] || [ $raON -lt $raOFF ] ||
8460                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
8461 }
8462 run_test 101d "file read with and without read-ahead enabled"
8463
8464 test_101e() {
8465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8466
8467         local file=$DIR/$tfile
8468         local size_KB=500  #KB
8469         local count=100
8470         local bsize=1024
8471
8472         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
8473         local need_KB=$((count * size_KB))
8474         [[ $free_KB -le $need_KB ]] &&
8475                 skip_env "Need free space $need_KB, have $free_KB"
8476
8477         echo "Creating $count ${size_KB}K test files"
8478         for ((i = 0; i < $count; i++)); do
8479                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
8480         done
8481
8482         echo "Cancel LRU locks on lustre client to flush the client cache"
8483         cancel_lru_locks $OSC
8484
8485         echo "Reset readahead stats"
8486         $LCTL set_param -n llite.*.read_ahead_stats 0
8487
8488         for ((i = 0; i < $count; i++)); do
8489                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
8490         done
8491
8492         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8493                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
8494
8495         for ((i = 0; i < $count; i++)); do
8496                 rm -rf $file.$i 2>/dev/null
8497         done
8498
8499         #10000 means 20% reads are missing in readahead
8500         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
8501 }
8502 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
8503
8504 test_101f() {
8505         which iozone || skip_env "no iozone installed"
8506
8507         local old_debug=$($LCTL get_param debug)
8508         old_debug=${old_debug#*=}
8509         $LCTL set_param debug="reada mmap"
8510
8511         # create a test file
8512         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
8513
8514         echo Cancel LRU locks on lustre client to flush the client cache
8515         cancel_lru_locks osc
8516
8517         echo Reset readahead stats
8518         $LCTL set_param -n llite.*.read_ahead_stats 0
8519
8520         echo mmap read the file with small block size
8521         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
8522                 > /dev/null 2>&1
8523
8524         echo checking missing pages
8525         $LCTL get_param llite.*.read_ahead_stats
8526         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8527                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8528
8529         $LCTL set_param debug="$old_debug"
8530         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
8531         rm -f $DIR/$tfile
8532 }
8533 run_test 101f "check mmap read performance"
8534
8535 test_101g_brw_size_test() {
8536         local mb=$1
8537         local pages=$((mb * 1048576 / PAGE_SIZE))
8538         local file=$DIR/$tfile
8539
8540         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
8541                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
8542         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
8543                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
8544                         return 2
8545         done
8546
8547         stack_trap "rm -f $file" EXIT
8548         $LCTL set_param -n osc.*.rpc_stats=0
8549
8550         # 10 RPCs should be enough for the test
8551         local count=10
8552         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
8553                 { error "dd write ${mb} MB blocks failed"; return 3; }
8554         cancel_lru_locks osc
8555         dd of=/dev/null if=$file bs=${mb}M count=$count ||
8556                 { error "dd write ${mb} MB blocks failed"; return 4; }
8557
8558         # calculate number of full-sized read and write RPCs
8559         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
8560                 sed -n '/pages per rpc/,/^$/p' |
8561                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
8562                 END { print reads,writes }'))
8563         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
8564                 return 5
8565         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
8566                 return 6
8567
8568         return 0
8569 }
8570
8571 test_101g() {
8572         remote_ost_nodsh && skip "remote OST with nodsh"
8573
8574         local rpcs
8575         local osts=$(get_facets OST)
8576         local list=$(comma_list $(osts_nodes))
8577         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8578         local brw_size="obdfilter.*.brw_size"
8579
8580         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8581
8582         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
8583
8584         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
8585                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
8586                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
8587            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
8588                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
8589                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
8590
8591                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
8592                         suffix="M"
8593
8594                 if [[ $orig_mb -lt 16 ]]; then
8595                         save_lustre_params $osts "$brw_size" > $p
8596                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
8597                                 error "set 16MB RPC size failed"
8598
8599                         echo "remount client to enable new RPC size"
8600                         remount_client $MOUNT || error "remount_client failed"
8601                 fi
8602
8603                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
8604                 # should be able to set brw_size=12, but no rpc_stats for that
8605                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
8606         fi
8607
8608         test_101g_brw_size_test 4 || error "4MB RPC test failed"
8609
8610         if [[ $orig_mb -lt 16 ]]; then
8611                 restore_lustre_params < $p
8612                 remount_client $MOUNT || error "remount_client restore failed"
8613         fi
8614
8615         rm -f $p $DIR/$tfile
8616 }
8617 run_test 101g "Big bulk(4/16 MiB) readahead"
8618
8619 setup_test102() {
8620         test_mkdir $DIR/$tdir
8621         chown $RUNAS_ID $DIR/$tdir
8622         STRIPE_SIZE=65536
8623         STRIPE_OFFSET=1
8624         STRIPE_COUNT=$OSTCOUNT
8625         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
8626
8627         trap cleanup_test102 EXIT
8628         cd $DIR
8629         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
8630         cd $DIR/$tdir
8631         for num in 1 2 3 4; do
8632                 for count in $(seq 1 $STRIPE_COUNT); do
8633                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
8634                                 local size=`expr $STRIPE_SIZE \* $num`
8635                                 local file=file"$num-$idx-$count"
8636                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
8637                         done
8638                 done
8639         done
8640
8641         cd $DIR
8642         $1 tar cf $TMP/f102.tar $tdir --xattrs
8643 }
8644
8645 cleanup_test102() {
8646         trap 0
8647         rm -f $TMP/f102.tar
8648         rm -rf $DIR/d0.sanity/d102
8649 }
8650
8651 test_102a() {
8652         [ "$UID" != 0 ] && skip "must run as root"
8653         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
8654                 skip_env "must have user_xattr"
8655
8656         [ -z "$(which setfattr 2>/dev/null)" ] &&
8657                 skip_env "could not find setfattr"
8658
8659         local testfile=$DIR/$tfile
8660
8661         touch $testfile
8662         echo "set/get xattr..."
8663         setfattr -n trusted.name1 -v value1 $testfile ||
8664                 error "setfattr -n trusted.name1=value1 $testfile failed"
8665         getfattr -n trusted.name1 $testfile 2> /dev/null |
8666           grep "trusted.name1=.value1" ||
8667                 error "$testfile missing trusted.name1=value1"
8668
8669         setfattr -n user.author1 -v author1 $testfile ||
8670                 error "setfattr -n user.author1=author1 $testfile failed"
8671         getfattr -n user.author1 $testfile 2> /dev/null |
8672           grep "user.author1=.author1" ||
8673                 error "$testfile missing trusted.author1=author1"
8674
8675         echo "listxattr..."
8676         setfattr -n trusted.name2 -v value2 $testfile ||
8677                 error "$testfile unable to set trusted.name2"
8678         setfattr -n trusted.name3 -v value3 $testfile ||
8679                 error "$testfile unable to set trusted.name3"
8680         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
8681             grep "trusted.name" | wc -l) -eq 3 ] ||
8682                 error "$testfile missing 3 trusted.name xattrs"
8683
8684         setfattr -n user.author2 -v author2 $testfile ||
8685                 error "$testfile unable to set user.author2"
8686         setfattr -n user.author3 -v author3 $testfile ||
8687                 error "$testfile unable to set user.author3"
8688         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
8689             grep "user.author" | wc -l) -eq 3 ] ||
8690                 error "$testfile missing 3 user.author xattrs"
8691
8692         echo "remove xattr..."
8693         setfattr -x trusted.name1 $testfile ||
8694                 error "$testfile error deleting trusted.name1"
8695         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
8696                 error "$testfile did not delete trusted.name1 xattr"
8697
8698         setfattr -x user.author1 $testfile ||
8699                 error "$testfile error deleting user.author1"
8700         echo "set lustre special xattr ..."
8701         $LFS setstripe -c1 $testfile
8702         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
8703                 awk -F "=" '/trusted.lov/ { print $2 }' )
8704         setfattr -n "trusted.lov" -v $lovea $testfile ||
8705                 error "$testfile doesn't ignore setting trusted.lov again"
8706         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
8707                 error "$testfile allow setting invalid trusted.lov"
8708         rm -f $testfile
8709 }
8710 run_test 102a "user xattr test =================================="
8711
8712 test_102b() {
8713         [ -z "$(which setfattr 2>/dev/null)" ] &&
8714                 skip_env "could not find setfattr"
8715         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8716
8717         # b10930: get/set/list trusted.lov xattr
8718         echo "get/set/list trusted.lov xattr ..."
8719         local testfile=$DIR/$tfile
8720         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8721                 error "setstripe failed"
8722         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
8723                 error "getstripe failed"
8724         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
8725                 error "can't get trusted.lov from $testfile"
8726
8727         local testfile2=${testfile}2
8728         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
8729                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
8730
8731         $MCREATE $testfile2
8732         setfattr -n trusted.lov -v $value $testfile2
8733         local stripe_size=$($LFS getstripe -S $testfile2)
8734         local stripe_count=$($LFS getstripe -c $testfile2)
8735         [[ $stripe_size -eq 65536 ]] ||
8736                 error "stripe size $stripe_size != 65536"
8737         [[ $stripe_count -eq $STRIPECOUNT ]] ||
8738                 error "stripe count $stripe_count != $STRIPECOUNT"
8739         rm -f $DIR/$tfile
8740 }
8741 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
8742
8743 test_102c() {
8744         [ -z "$(which setfattr 2>/dev/null)" ] &&
8745                 skip_env "could not find setfattr"
8746         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8747
8748         # b10930: get/set/list lustre.lov xattr
8749         echo "get/set/list lustre.lov xattr ..."
8750         test_mkdir $DIR/$tdir
8751         chown $RUNAS_ID $DIR/$tdir
8752         local testfile=$DIR/$tdir/$tfile
8753         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8754                 error "setstripe failed"
8755         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
8756                 error "getstripe failed"
8757         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
8758         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
8759
8760         local testfile2=${testfile}2
8761         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
8762                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
8763
8764         $RUNAS $MCREATE $testfile2
8765         $RUNAS setfattr -n lustre.lov -v $value $testfile2
8766         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
8767         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
8768         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
8769         [ $stripe_count -eq $STRIPECOUNT ] ||
8770                 error "stripe count $stripe_count != $STRIPECOUNT"
8771 }
8772 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
8773
8774 compare_stripe_info1() {
8775         local stripe_index_all_zero=true
8776
8777         for num in 1 2 3 4; do
8778                 for count in $(seq 1 $STRIPE_COUNT); do
8779                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
8780                                 local size=$((STRIPE_SIZE * num))
8781                                 local file=file"$num-$offset-$count"
8782                                 stripe_size=$($LFS getstripe -S $PWD/$file)
8783                                 [[ $stripe_size -ne $size ]] &&
8784                                     error "$file: size $stripe_size != $size"
8785                                 stripe_count=$($LFS getstripe -c $PWD/$file)
8786                                 # allow fewer stripes to be created, ORI-601
8787                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
8788                                     error "$file: count $stripe_count != $count"
8789                                 stripe_index=$($LFS getstripe -i $PWD/$file)
8790                                 [[ $stripe_index -ne 0 ]] &&
8791                                         stripe_index_all_zero=false
8792                         done
8793                 done
8794         done
8795         $stripe_index_all_zero &&
8796                 error "all files are being extracted starting from OST index 0"
8797         return 0
8798 }
8799
8800 have_xattrs_include() {
8801         tar --help | grep -q xattrs-include &&
8802                 echo --xattrs-include="lustre.*"
8803 }
8804
8805 test_102d() {
8806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8807         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8808
8809         XINC=$(have_xattrs_include)
8810         setup_test102
8811         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8812         cd $DIR/$tdir/$tdir
8813         compare_stripe_info1
8814 }
8815 run_test 102d "tar restore stripe info from tarfile,not keep osts"
8816
8817 test_102f() {
8818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8819         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8820
8821         XINC=$(have_xattrs_include)
8822         setup_test102
8823         test_mkdir $DIR/$tdir.restore
8824         cd $DIR
8825         tar cf - --xattrs $tdir | tar xf - \
8826                 -C $DIR/$tdir.restore --xattrs $XINC
8827         cd $DIR/$tdir.restore/$tdir
8828         compare_stripe_info1
8829 }
8830 run_test 102f "tar copy files, not keep osts"
8831
8832 grow_xattr() {
8833         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
8834                 skip "must have user_xattr"
8835         [ -z "$(which setfattr 2>/dev/null)" ] &&
8836                 skip_env "could not find setfattr"
8837         [ -z "$(which getfattr 2>/dev/null)" ] &&
8838                 skip_env "could not find getfattr"
8839
8840         local xsize=${1:-1024}  # in bytes
8841         local file=$DIR/$tfile
8842         local value="$(generate_string $xsize)"
8843         local xbig=trusted.big
8844         local toobig=$2
8845
8846         touch $file
8847         log "save $xbig on $file"
8848         if [ -z "$toobig" ]
8849         then
8850                 setfattr -n $xbig -v $value $file ||
8851                         error "saving $xbig on $file failed"
8852         else
8853                 setfattr -n $xbig -v $value $file &&
8854                         error "saving $xbig on $file succeeded"
8855                 return 0
8856         fi
8857
8858         local orig=$(get_xattr_value $xbig $file)
8859         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
8860
8861         local xsml=trusted.sml
8862         log "save $xsml on $file"
8863         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
8864
8865         local new=$(get_xattr_value $xbig $file)
8866         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
8867
8868         log "grow $xsml on $file"
8869         setfattr -n $xsml -v "$value" $file ||
8870                 error "growing $xsml on $file failed"
8871
8872         new=$(get_xattr_value $xbig $file)
8873         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
8874         log "$xbig still valid after growing $xsml"
8875
8876         rm -f $file
8877 }
8878
8879 test_102h() { # bug 15777
8880         grow_xattr 1024
8881 }
8882 run_test 102h "grow xattr from inside inode to external block"
8883
8884 test_102ha() {
8885         large_xattr_enabled || skip_env "ea_inode feature disabled"
8886
8887         echo "setting xattr of max xattr size: $(max_xattr_size)"
8888         grow_xattr $(max_xattr_size)
8889
8890         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
8891         echo "This should fail:"
8892         grow_xattr $(($(max_xattr_size) + 10)) 1
8893 }
8894 run_test 102ha "grow xattr from inside inode to external inode"
8895
8896 test_102i() { # bug 17038
8897         [ -z "$(which getfattr 2>/dev/null)" ] &&
8898                 skip "could not find getfattr"
8899
8900         touch $DIR/$tfile
8901         ln -s $DIR/$tfile $DIR/${tfile}link
8902         getfattr -n trusted.lov $DIR/$tfile ||
8903                 error "lgetxattr on $DIR/$tfile failed"
8904         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
8905                 grep -i "no such attr" ||
8906                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
8907         rm -f $DIR/$tfile $DIR/${tfile}link
8908 }
8909 run_test 102i "lgetxattr test on symbolic link ============"
8910
8911 test_102j() {
8912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8913         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8914
8915         XINC=$(have_xattrs_include)
8916         setup_test102 "$RUNAS"
8917         chown $RUNAS_ID $DIR/$tdir
8918         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8919         cd $DIR/$tdir/$tdir
8920         compare_stripe_info1 "$RUNAS"
8921 }
8922 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
8923
8924 test_102k() {
8925         [ -z "$(which setfattr 2>/dev/null)" ] &&
8926                 skip "could not find setfattr"
8927
8928         touch $DIR/$tfile
8929         # b22187 just check that does not crash for regular file.
8930         setfattr -n trusted.lov $DIR/$tfile
8931         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
8932         local test_kdir=$DIR/$tdir
8933         test_mkdir $test_kdir
8934         local default_size=$($LFS getstripe -S $test_kdir)
8935         local default_count=$($LFS getstripe -c $test_kdir)
8936         local default_offset=$($LFS getstripe -i $test_kdir)
8937         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
8938                 error 'dir setstripe failed'
8939         setfattr -n trusted.lov $test_kdir
8940         local stripe_size=$($LFS getstripe -S $test_kdir)
8941         local stripe_count=$($LFS getstripe -c $test_kdir)
8942         local stripe_offset=$($LFS getstripe -i $test_kdir)
8943         [ $stripe_size -eq $default_size ] ||
8944                 error "stripe size $stripe_size != $default_size"
8945         [ $stripe_count -eq $default_count ] ||
8946                 error "stripe count $stripe_count != $default_count"
8947         [ $stripe_offset -eq $default_offset ] ||
8948                 error "stripe offset $stripe_offset != $default_offset"
8949         rm -rf $DIR/$tfile $test_kdir
8950 }
8951 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
8952
8953 test_102l() {
8954         [ -z "$(which getfattr 2>/dev/null)" ] &&
8955                 skip "could not find getfattr"
8956
8957         # LU-532 trusted. xattr is invisible to non-root
8958         local testfile=$DIR/$tfile
8959
8960         touch $testfile
8961
8962         echo "listxattr as user..."
8963         chown $RUNAS_ID $testfile
8964         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
8965             grep -q "trusted" &&
8966                 error "$testfile trusted xattrs are user visible"
8967
8968         return 0;
8969 }
8970 run_test 102l "listxattr size test =================================="
8971
8972 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
8973         local path=$DIR/$tfile
8974         touch $path
8975
8976         listxattr_size_check $path || error "listattr_size_check $path failed"
8977 }
8978 run_test 102m "Ensure listxattr fails on small bufffer ========"
8979
8980 cleanup_test102
8981
8982 getxattr() { # getxattr path name
8983         # Return the base64 encoding of the value of xattr name on path.
8984         local path=$1
8985         local name=$2
8986
8987         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
8988         # file: $path
8989         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8990         #
8991         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8992
8993         getfattr --absolute-names --encoding=base64 --name=$name $path |
8994                 awk -F= -v name=$name '$1 == name {
8995                         print substr($0, index($0, "=") + 1);
8996         }'
8997 }
8998
8999 test_102n() { # LU-4101 mdt: protect internal xattrs
9000         [ -z "$(which setfattr 2>/dev/null)" ] &&
9001                 skip "could not find setfattr"
9002         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
9003         then
9004                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
9005         fi
9006
9007         local file0=$DIR/$tfile.0
9008         local file1=$DIR/$tfile.1
9009         local xattr0=$TMP/$tfile.0
9010         local xattr1=$TMP/$tfile.1
9011         local namelist="lov lma lmv link fid version som hsm"
9012         local name
9013         local value
9014
9015         rm -rf $file0 $file1 $xattr0 $xattr1
9016         touch $file0 $file1
9017
9018         # Get 'before' xattrs of $file1.
9019         getfattr --absolute-names --dump --match=- $file1 > $xattr0
9020
9021         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
9022                 namelist+=" lfsck_namespace"
9023         for name in $namelist; do
9024                 # Try to copy xattr from $file0 to $file1.
9025                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9026
9027                 setfattr --name=trusted.$name --value="$value" $file1 ||
9028                         error "setxattr 'trusted.$name' failed"
9029
9030                 # Try to set a garbage xattr.
9031                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9032
9033                 if [[ x$name == "xlov" ]]; then
9034                         setfattr --name=trusted.lov --value="$value" $file1 &&
9035                         error "setxattr invalid 'trusted.lov' success"
9036                 else
9037                         setfattr --name=trusted.$name --value="$value" $file1 ||
9038                                 error "setxattr invalid 'trusted.$name' failed"
9039                 fi
9040
9041                 # Try to remove the xattr from $file1. We don't care if this
9042                 # appears to succeed or fail, we just don't want there to be
9043                 # any changes or crashes.
9044                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9045         done
9046
9047         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
9048         then
9049                 name="lfsck_ns"
9050                 # Try to copy xattr from $file0 to $file1.
9051                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9052
9053                 setfattr --name=trusted.$name --value="$value" $file1 ||
9054                         error "setxattr 'trusted.$name' failed"
9055
9056                 # Try to set a garbage xattr.
9057                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9058
9059                 setfattr --name=trusted.$name --value="$value" $file1 ||
9060                         error "setxattr 'trusted.$name' failed"
9061
9062                 # Try to remove the xattr from $file1. We don't care if this
9063                 # appears to succeed or fail, we just don't want there to be
9064                 # any changes or crashes.
9065                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9066         fi
9067
9068         # Get 'after' xattrs of file1.
9069         getfattr --absolute-names --dump --match=- $file1 > $xattr1
9070
9071         if ! diff $xattr0 $xattr1; then
9072                 error "before and after xattrs of '$file1' differ"
9073         fi
9074
9075         rm -rf $file0 $file1 $xattr0 $xattr1
9076
9077         return 0
9078 }
9079 run_test 102n "silently ignore setxattr on internal trusted xattrs"
9080
9081 test_102p() { # LU-4703 setxattr did not check ownership
9082         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
9083                 skip "MDS needs to be at least 2.5.56"
9084
9085         local testfile=$DIR/$tfile
9086
9087         touch $testfile
9088
9089         echo "setfacl as user..."
9090         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
9091         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
9092
9093         echo "setfattr as user..."
9094         setfacl -m "u:$RUNAS_ID:---" $testfile
9095         $RUNAS setfattr -x system.posix_acl_access $testfile
9096         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
9097 }
9098 run_test 102p "check setxattr(2) correctly fails without permission"
9099
9100 test_102q() {
9101         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
9102                 skip "MDS needs to be at least 2.6.92"
9103
9104         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
9105 }
9106 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
9107
9108 test_102r() {
9109         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
9110                 skip "MDS needs to be at least 2.6.93"
9111
9112         touch $DIR/$tfile || error "touch"
9113         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
9114         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
9115         rm $DIR/$tfile || error "rm"
9116
9117         #normal directory
9118         mkdir -p $DIR/$tdir || error "mkdir"
9119         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9120         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9121         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9122                 error "$testfile error deleting user.author1"
9123         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9124                 grep "user.$(basename $tdir)" &&
9125                 error "$tdir did not delete user.$(basename $tdir)"
9126         rmdir $DIR/$tdir || error "rmdir"
9127
9128         #striped directory
9129         test_mkdir $DIR/$tdir
9130         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9131         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9132         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9133                 error "$testfile error deleting user.author1"
9134         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9135                 grep "user.$(basename $tdir)" &&
9136                 error "$tdir did not delete user.$(basename $tdir)"
9137         rmdir $DIR/$tdir || error "rm striped dir"
9138 }
9139 run_test 102r "set EAs with empty values"
9140
9141 test_102s() {
9142         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9143                 skip "MDS needs to be at least 2.11.52"
9144
9145         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9146
9147         save_lustre_params client "llite.*.xattr_cache" > $save
9148
9149         for cache in 0 1; do
9150                 lctl set_param llite.*.xattr_cache=$cache
9151
9152                 rm -f $DIR/$tfile
9153                 touch $DIR/$tfile || error "touch"
9154                 for prefix in lustre security system trusted user; do
9155                         # Note getxattr() may fail with 'Operation not
9156                         # supported' or 'No such attribute' depending
9157                         # on prefix and cache.
9158                         getfattr -n $prefix.n102s $DIR/$tfile &&
9159                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
9160                 done
9161         done
9162
9163         restore_lustre_params < $save
9164 }
9165 run_test 102s "getting nonexistent xattrs should fail"
9166
9167 test_102t() {
9168         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9169                 skip "MDS needs to be at least 2.11.52"
9170
9171         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9172
9173         save_lustre_params client "llite.*.xattr_cache" > $save
9174
9175         for cache in 0 1; do
9176                 lctl set_param llite.*.xattr_cache=$cache
9177
9178                 for buf_size in 0 256; do
9179                         rm -f $DIR/$tfile
9180                         touch $DIR/$tfile || error "touch"
9181                         setfattr -n user.multiop $DIR/$tfile
9182                         $MULTIOP $DIR/$tfile oa$buf_size ||
9183                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
9184                 done
9185         done
9186
9187         restore_lustre_params < $save
9188 }
9189 run_test 102t "zero length xattr values handled correctly"
9190
9191 run_acl_subtest()
9192 {
9193     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
9194     return $?
9195 }
9196
9197 test_103a() {
9198         [ "$UID" != 0 ] && skip "must run as root"
9199         $GSS && skip_env "could not run under gss"
9200         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
9201                 skip_env "must have acl enabled"
9202         [ -z "$(which setfacl 2>/dev/null)" ] &&
9203                 skip_env "could not find setfacl"
9204         remote_mds_nodsh && skip "remote MDS with nodsh"
9205
9206         gpasswd -a daemon bin                           # LU-5641
9207         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
9208
9209         declare -a identity_old
9210
9211         for num in $(seq $MDSCOUNT); do
9212                 switch_identity $num true || identity_old[$num]=$?
9213         done
9214
9215         SAVE_UMASK=$(umask)
9216         umask 0022
9217         mkdir -p $DIR/$tdir
9218         cd $DIR/$tdir
9219
9220         echo "performing cp ..."
9221         run_acl_subtest cp || error "run_acl_subtest cp failed"
9222         echo "performing getfacl-noacl..."
9223         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
9224         echo "performing misc..."
9225         run_acl_subtest misc || error  "misc test failed"
9226         echo "performing permissions..."
9227         run_acl_subtest permissions || error "permissions failed"
9228         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
9229         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
9230                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
9231                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
9232         then
9233                 echo "performing permissions xattr..."
9234                 run_acl_subtest permissions_xattr ||
9235                         error "permissions_xattr failed"
9236         fi
9237         echo "performing setfacl..."
9238         run_acl_subtest setfacl || error  "setfacl test failed"
9239
9240         # inheritance test got from HP
9241         echo "performing inheritance..."
9242         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
9243         chmod +x make-tree || error "chmod +x failed"
9244         run_acl_subtest inheritance || error "inheritance test failed"
9245         rm -f make-tree
9246
9247         echo "LU-974 ignore umask when acl is enabled..."
9248         run_acl_subtest 974 || error "LU-974 umask test failed"
9249         if [ $MDSCOUNT -ge 2 ]; then
9250                 run_acl_subtest 974_remote ||
9251                         error "LU-974 umask test failed under remote dir"
9252         fi
9253
9254         echo "LU-2561 newly created file is same size as directory..."
9255         if [ "$mds1_FSTYPE" != "zfs" ]; then
9256                 run_acl_subtest 2561 || error "LU-2561 test failed"
9257         else
9258                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
9259         fi
9260
9261         run_acl_subtest 4924 || error "LU-4924 test failed"
9262
9263         cd $SAVE_PWD
9264         umask $SAVE_UMASK
9265
9266         for num in $(seq $MDSCOUNT); do
9267                 if [ "${identity_old[$num]}" = 1 ]; then
9268                         switch_identity $num false || identity_old[$num]=$?
9269                 fi
9270         done
9271 }
9272 run_test 103a "acl test"
9273
9274 test_103b() {
9275         declare -a pids
9276         local U
9277
9278         for U in {0..511}; do
9279                 {
9280                 local O=$(printf "%04o" $U)
9281
9282                 umask $(printf "%04o" $((511 ^ $O)))
9283                 $LFS setstripe -c 1 $DIR/$tfile.s$O
9284                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
9285
9286                 (( $S == ($O & 0666) )) ||
9287                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
9288
9289                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
9290                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
9291                 (( $S == ($O & 0666) )) ||
9292                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
9293
9294                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
9295                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
9296                 (( $S == ($O & 0666) )) ||
9297                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
9298                 rm -f $DIR/$tfile.[smp]$0
9299                 } &
9300                 local pid=$!
9301
9302                 # limit the concurrently running threads to 64. LU-11878
9303                 local idx=$((U % 64))
9304                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
9305                 pids[idx]=$pid
9306         done
9307         wait
9308 }
9309 run_test 103b "umask lfs setstripe"
9310
9311 test_103c() {
9312         mkdir -p $DIR/$tdir
9313         cp -rp $DIR/$tdir $DIR/$tdir.bak
9314
9315         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
9316                 error "$DIR/$tdir shouldn't contain default ACL"
9317         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
9318                 error "$DIR/$tdir.bak shouldn't contain default ACL"
9319         true
9320 }
9321 run_test 103c "'cp -rp' won't set empty acl"
9322
9323 test_104a() {
9324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9325
9326         touch $DIR/$tfile
9327         lfs df || error "lfs df failed"
9328         lfs df -ih || error "lfs df -ih failed"
9329         lfs df -h $DIR || error "lfs df -h $DIR failed"
9330         lfs df -i $DIR || error "lfs df -i $DIR failed"
9331         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
9332         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
9333
9334         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
9335         lctl --device %$OSC deactivate
9336         lfs df || error "lfs df with deactivated OSC failed"
9337         lctl --device %$OSC activate
9338         # wait the osc back to normal
9339         wait_osc_import_ready client ost
9340
9341         lfs df || error "lfs df with reactivated OSC failed"
9342         rm -f $DIR/$tfile
9343 }
9344 run_test 104a "lfs df [-ih] [path] test ========================="
9345
9346 test_104b() {
9347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9348         [ $RUNAS_ID -eq $UID ] &&
9349                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9350
9351         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
9352                         grep "Permission denied" | wc -l)))
9353         if [ $denied_cnt -ne 0 ]; then
9354                 error "lfs check servers test failed"
9355         fi
9356 }
9357 run_test 104b "$RUNAS lfs check servers test ===================="
9358
9359 test_105a() {
9360         # doesn't work on 2.4 kernels
9361         touch $DIR/$tfile
9362         if $(flock_is_enabled); then
9363                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
9364         else
9365                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
9366         fi
9367         rm -f $DIR/$tfile
9368 }
9369 run_test 105a "flock when mounted without -o flock test ========"
9370
9371 test_105b() {
9372         touch $DIR/$tfile
9373         if $(flock_is_enabled); then
9374                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
9375         else
9376                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
9377         fi
9378         rm -f $DIR/$tfile
9379 }
9380 run_test 105b "fcntl when mounted without -o flock test ========"
9381
9382 test_105c() {
9383         touch $DIR/$tfile
9384         if $(flock_is_enabled); then
9385                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
9386         else
9387                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
9388         fi
9389         rm -f $DIR/$tfile
9390 }
9391 run_test 105c "lockf when mounted without -o flock test"
9392
9393 test_105d() { # bug 15924
9394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9395
9396         test_mkdir $DIR/$tdir
9397         flock_is_enabled || skip_env "mount w/o flock enabled"
9398         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
9399         $LCTL set_param fail_loc=0x80000315
9400         flocks_test 2 $DIR/$tdir
9401 }
9402 run_test 105d "flock race (should not freeze) ========"
9403
9404 test_105e() { # bug 22660 && 22040
9405         flock_is_enabled || skip_env "mount w/o flock enabled"
9406
9407         touch $DIR/$tfile
9408         flocks_test 3 $DIR/$tfile
9409 }
9410 run_test 105e "Two conflicting flocks from same process"
9411
9412 test_106() { #bug 10921
9413         test_mkdir $DIR/$tdir
9414         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
9415         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
9416 }
9417 run_test 106 "attempt exec of dir followed by chown of that dir"
9418
9419 test_107() {
9420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9421
9422         CDIR=`pwd`
9423         local file=core
9424
9425         cd $DIR
9426         rm -f $file
9427
9428         local save_pattern=$(sysctl -n kernel.core_pattern)
9429         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
9430         sysctl -w kernel.core_pattern=$file
9431         sysctl -w kernel.core_uses_pid=0
9432
9433         ulimit -c unlimited
9434         sleep 60 &
9435         SLEEPPID=$!
9436
9437         sleep 1
9438
9439         kill -s 11 $SLEEPPID
9440         wait $SLEEPPID
9441         if [ -e $file ]; then
9442                 size=`stat -c%s $file`
9443                 [ $size -eq 0 ] && error "Fail to create core file $file"
9444         else
9445                 error "Fail to create core file $file"
9446         fi
9447         rm -f $file
9448         sysctl -w kernel.core_pattern=$save_pattern
9449         sysctl -w kernel.core_uses_pid=$save_uses_pid
9450         cd $CDIR
9451 }
9452 run_test 107 "Coredump on SIG"
9453
9454 test_110() {
9455         test_mkdir $DIR/$tdir
9456         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
9457         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
9458                 error "mkdir with 256 char should fail, but did not"
9459         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
9460                 error "create with 255 char failed"
9461         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
9462                 error "create with 256 char should fail, but did not"
9463
9464         ls -l $DIR/$tdir
9465         rm -rf $DIR/$tdir
9466 }
9467 run_test 110 "filename length checking"
9468
9469 #
9470 # Purpose: To verify dynamic thread (OSS) creation.
9471 #
9472 test_115() {
9473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9474         remote_ost_nodsh && skip "remote OST with nodsh"
9475
9476         # Lustre does not stop service threads once they are started.
9477         # Reset number of running threads to default.
9478         stopall
9479         setupall
9480
9481         local OSTIO_pre
9482         local save_params="$TMP/sanity-$TESTNAME.parameters"
9483
9484         # Get ll_ost_io count before I/O
9485         OSTIO_pre=$(do_facet ost1 \
9486                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
9487         # Exit if lustre is not running (ll_ost_io not running).
9488         [ -z "$OSTIO_pre" ] && error "no OSS threads"
9489
9490         echo "Starting with $OSTIO_pre threads"
9491         local thread_max=$((OSTIO_pre * 2))
9492         local rpc_in_flight=$((thread_max * 2))
9493         # Number of I/O Process proposed to be started.
9494         local nfiles
9495         local facets=$(get_facets OST)
9496
9497         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
9498         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
9499
9500         # Set in_flight to $rpc_in_flight
9501         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
9502                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
9503         nfiles=${rpc_in_flight}
9504         # Set ost thread_max to $thread_max
9505         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
9506
9507         # 5 Minutes should be sufficient for max number of OSS
9508         # threads(thread_max) to be created.
9509         local timeout=300
9510
9511         # Start I/O.
9512         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
9513         test_mkdir $DIR/$tdir
9514         for i in $(seq $nfiles); do
9515                 local file=$DIR/$tdir/${tfile}-$i
9516                 $LFS setstripe -c -1 -i 0 $file
9517                 ($WTL $file $timeout)&
9518         done
9519
9520         # I/O Started - Wait for thread_started to reach thread_max or report
9521         # error if thread_started is more than thread_max.
9522         echo "Waiting for thread_started to reach thread_max"
9523         local thread_started=0
9524         local end_time=$((SECONDS + timeout))
9525
9526         while [ $SECONDS -le $end_time ] ; do
9527                 echo -n "."
9528                 # Get ost i/o thread_started count.
9529                 thread_started=$(do_facet ost1 \
9530                         "$LCTL get_param \
9531                         ost.OSS.ost_io.threads_started | cut -d= -f2")
9532                 # Break out if thread_started is equal/greater than thread_max
9533                 if [[ $thread_started -ge $thread_max ]]; then
9534                         echo ll_ost_io thread_started $thread_started, \
9535                                 equal/greater than thread_max $thread_max
9536                         break
9537                 fi
9538                 sleep 1
9539         done
9540
9541         # Cleanup - We have the numbers, Kill i/o jobs if running.
9542         jobcount=($(jobs -p))
9543         for i in $(seq 0 $((${#jobcount[@]}-1)))
9544         do
9545                 kill -9 ${jobcount[$i]}
9546                 if [ $? -ne 0 ] ; then
9547                         echo Warning: \
9548                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
9549                 fi
9550         done
9551
9552         # Cleanup files left by WTL binary.
9553         for i in $(seq $nfiles); do
9554                 local file=$DIR/$tdir/${tfile}-$i
9555                 rm -rf $file
9556                 if [ $? -ne 0 ] ; then
9557                         echo "Warning: Failed to delete file $file"
9558                 fi
9559         done
9560
9561         restore_lustre_params <$save_params
9562         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
9563
9564         # Error out if no new thread has started or Thread started is greater
9565         # than thread max.
9566         if [[ $thread_started -le $OSTIO_pre ||
9567                         $thread_started -gt $thread_max ]]; then
9568                 error "ll_ost_io: thread_started $thread_started" \
9569                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
9570                       "No new thread started or thread started greater " \
9571                       "than thread_max."
9572         fi
9573 }
9574 run_test 115 "verify dynamic thread creation===================="
9575
9576 free_min_max () {
9577         wait_delete_completed
9578         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
9579         echo "OST kbytes available: ${AVAIL[@]}"
9580         MAXV=${AVAIL[0]}
9581         MAXI=0
9582         MINV=${AVAIL[0]}
9583         MINI=0
9584         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
9585                 #echo OST $i: ${AVAIL[i]}kb
9586                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
9587                         MAXV=${AVAIL[i]}
9588                         MAXI=$i
9589                 fi
9590                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
9591                         MINV=${AVAIL[i]}
9592                         MINI=$i
9593                 fi
9594         done
9595         echo "Min free space: OST $MINI: $MINV"
9596         echo "Max free space: OST $MAXI: $MAXV"
9597 }
9598
9599 test_116a() { # was previously test_116()
9600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9601         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9602         remote_mds_nodsh && skip "remote MDS with nodsh"
9603
9604         echo -n "Free space priority "
9605         do_facet $SINGLEMDS lctl get_param -n lo*.*-mdtlov.qos_prio_free |
9606                 head -n1
9607         declare -a AVAIL
9608         free_min_max
9609
9610         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
9611         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
9612         trap simple_cleanup_common EXIT
9613
9614         # Check if we need to generate uneven OSTs
9615         test_mkdir -p $DIR/$tdir/OST${MINI}
9616         local FILL=$((MINV / 4))
9617         local DIFF=$((MAXV - MINV))
9618         local DIFF2=$((DIFF * 100 / MINV))
9619
9620         local threshold=$(do_facet $SINGLEMDS \
9621                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
9622         threshold=${threshold%%%}
9623         echo -n "Check for uneven OSTs: "
9624         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
9625
9626         if [[ $DIFF2 -gt $threshold ]]; then
9627                 echo "ok"
9628                 echo "Don't need to fill OST$MINI"
9629         else
9630                 # generate uneven OSTs. Write 2% over the QOS threshold value
9631                 echo "no"
9632                 DIFF=$((threshold - DIFF2 + 2))
9633                 DIFF2=$((MINV * DIFF / 100))
9634                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
9635                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
9636                         error "setstripe failed"
9637                 DIFF=$((DIFF2 / 2048))
9638                 i=0
9639                 while [ $i -lt $DIFF ]; do
9640                         i=$((i + 1))
9641                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
9642                                 bs=2M count=1 2>/dev/null
9643                         echo -n .
9644                 done
9645                 echo .
9646                 sync
9647                 sleep_maxage
9648                 free_min_max
9649         fi
9650
9651         DIFF=$((MAXV - MINV))
9652         DIFF2=$((DIFF * 100 / MINV))
9653         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
9654         if [ $DIFF2 -gt $threshold ]; then
9655                 echo "ok"
9656         else
9657                 echo "failed - QOS mode won't be used"
9658                 simple_cleanup_common
9659                 skip "QOS imbalance criteria not met"
9660         fi
9661
9662         MINI1=$MINI
9663         MINV1=$MINV
9664         MAXI1=$MAXI
9665         MAXV1=$MAXV
9666
9667         # now fill using QOS
9668         $LFS setstripe -c 1 $DIR/$tdir
9669         FILL=$((FILL / 200))
9670         if [ $FILL -gt 600 ]; then
9671                 FILL=600
9672         fi
9673         echo "writing $FILL files to QOS-assigned OSTs"
9674         i=0
9675         while [ $i -lt $FILL ]; do
9676                 i=$((i + 1))
9677                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
9678                         count=1 2>/dev/null
9679                 echo -n .
9680         done
9681         echo "wrote $i 200k files"
9682         sync
9683         sleep_maxage
9684
9685         echo "Note: free space may not be updated, so measurements might be off"
9686         free_min_max
9687         DIFF2=$((MAXV - MINV))
9688         echo "free space delta: orig $DIFF final $DIFF2"
9689         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
9690         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
9691         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
9692         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
9693         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
9694         if [[ $DIFF -gt 0 ]]; then
9695                 FILL=$((DIFF2 * 100 / DIFF - 100))
9696                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
9697         fi
9698
9699         # Figure out which files were written where
9700         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9701                awk '/'$MINI1': / {print $2; exit}')
9702         echo $UUID
9703         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9704         echo "$MINC files created on smaller OST $MINI1"
9705         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9706                awk '/'$MAXI1': / {print $2; exit}')
9707         echo $UUID
9708         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9709         echo "$MAXC files created on larger OST $MAXI1"
9710         if [[ $MINC -gt 0 ]]; then
9711                 FILL=$((MAXC * 100 / MINC - 100))
9712                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
9713         fi
9714         [[ $MAXC -gt $MINC ]] ||
9715                 error_ignore LU-9 "stripe QOS didn't balance free space"
9716         simple_cleanup_common
9717 }
9718 run_test 116a "stripe QOS: free space balance ==================="
9719
9720 test_116b() { # LU-2093
9721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9722         remote_mds_nodsh && skip "remote MDS with nodsh"
9723
9724 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
9725         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
9726                        lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
9727         [ -z "$old_rr" ] && skip "no QOS"
9728         do_facet $SINGLEMDS lctl set_param \
9729                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
9730         mkdir -p $DIR/$tdir
9731         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
9732         createmany -o $DIR/$tdir/f- 20 || error "can't create"
9733         do_facet $SINGLEMDS lctl set_param fail_loc=0
9734         rm -rf $DIR/$tdir
9735         do_facet $SINGLEMDS lctl set_param \
9736                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
9737 }
9738 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
9739
9740 test_117() # bug 10891
9741 {
9742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9743
9744         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
9745         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
9746         lctl set_param fail_loc=0x21e
9747         > $DIR/$tfile || error "truncate failed"
9748         lctl set_param fail_loc=0
9749         echo "Truncate succeeded."
9750         rm -f $DIR/$tfile
9751 }
9752 run_test 117 "verify osd extend =========="
9753
9754 NO_SLOW_RESENDCOUNT=4
9755 export OLD_RESENDCOUNT=""
9756 set_resend_count () {
9757         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
9758         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
9759         lctl set_param -n $PROC_RESENDCOUNT $1
9760         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
9761 }
9762
9763 # for reduce test_118* time (b=14842)
9764 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9765
9766 # Reset async IO behavior after error case
9767 reset_async() {
9768         FILE=$DIR/reset_async
9769
9770         # Ensure all OSCs are cleared
9771         $LFS setstripe -c -1 $FILE
9772         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
9773         sync
9774         rm $FILE
9775 }
9776
9777 test_118a() #bug 11710
9778 {
9779         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9780
9781         reset_async
9782
9783         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9784         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9785         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9786
9787         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9788                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9789                 return 1;
9790         fi
9791         rm -f $DIR/$tfile
9792 }
9793 run_test 118a "verify O_SYNC works =========="
9794
9795 test_118b()
9796 {
9797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9798         remote_ost_nodsh && skip "remote OST with nodsh"
9799
9800         reset_async
9801
9802         #define OBD_FAIL_SRV_ENOENT 0x217
9803         set_nodes_failloc "$(osts_nodes)" 0x217
9804         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9805         RC=$?
9806         set_nodes_failloc "$(osts_nodes)" 0
9807         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9808         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9809                     grep -c writeback)
9810
9811         if [[ $RC -eq 0 ]]; then
9812                 error "Must return error due to dropped pages, rc=$RC"
9813                 return 1;
9814         fi
9815
9816         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9817                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9818                 return 1;
9819         fi
9820
9821         echo "Dirty pages not leaked on ENOENT"
9822
9823         # Due to the above error the OSC will issue all RPCs syncronously
9824         # until a subsequent RPC completes successfully without error.
9825         $MULTIOP $DIR/$tfile Ow4096yc
9826         rm -f $DIR/$tfile
9827
9828         return 0
9829 }
9830 run_test 118b "Reclaim dirty pages on fatal error =========="
9831
9832 test_118c()
9833 {
9834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9835
9836         # for 118c, restore the original resend count, LU-1940
9837         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
9838                                 set_resend_count $OLD_RESENDCOUNT
9839         remote_ost_nodsh && skip "remote OST with nodsh"
9840
9841         reset_async
9842
9843         #define OBD_FAIL_OST_EROFS               0x216
9844         set_nodes_failloc "$(osts_nodes)" 0x216
9845
9846         # multiop should block due to fsync until pages are written
9847         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9848         MULTIPID=$!
9849         sleep 1
9850
9851         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9852                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9853         fi
9854
9855         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9856                     grep -c writeback)
9857         if [[ $WRITEBACK -eq 0 ]]; then
9858                 error "No page in writeback, writeback=$WRITEBACK"
9859         fi
9860
9861         set_nodes_failloc "$(osts_nodes)" 0
9862         wait $MULTIPID
9863         RC=$?
9864         if [[ $RC -ne 0 ]]; then
9865                 error "Multiop fsync failed, rc=$RC"
9866         fi
9867
9868         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9869         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9870                     grep -c writeback)
9871         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9872                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9873         fi
9874
9875         rm -f $DIR/$tfile
9876         echo "Dirty pages flushed via fsync on EROFS"
9877         return 0
9878 }
9879 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
9880
9881 # continue to use small resend count to reduce test_118* time (b=14842)
9882 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9883
9884 test_118d()
9885 {
9886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9887         remote_ost_nodsh && skip "remote OST with nodsh"
9888
9889         reset_async
9890
9891         #define OBD_FAIL_OST_BRW_PAUSE_BULK
9892         set_nodes_failloc "$(osts_nodes)" 0x214
9893         # multiop should block due to fsync until pages are written
9894         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9895         MULTIPID=$!
9896         sleep 1
9897
9898         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9899                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9900         fi
9901
9902         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9903                     grep -c writeback)
9904         if [[ $WRITEBACK -eq 0 ]]; then
9905                 error "No page in writeback, writeback=$WRITEBACK"
9906         fi
9907
9908         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
9909         set_nodes_failloc "$(osts_nodes)" 0
9910
9911         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9912         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9913                     grep -c writeback)
9914         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9915                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9916         fi
9917
9918         rm -f $DIR/$tfile
9919         echo "Dirty pages gaurenteed flushed via fsync"
9920         return 0
9921 }
9922 run_test 118d "Fsync validation inject a delay of the bulk =========="
9923
9924 test_118f() {
9925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9926
9927         reset_async
9928
9929         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
9930         lctl set_param fail_loc=0x8000040a
9931
9932         # Should simulate EINVAL error which is fatal
9933         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9934         RC=$?
9935         if [[ $RC -eq 0 ]]; then
9936                 error "Must return error due to dropped pages, rc=$RC"
9937         fi
9938
9939         lctl set_param fail_loc=0x0
9940
9941         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9942         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9943         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9944                     grep -c writeback)
9945         if [[ $LOCKED -ne 0 ]]; then
9946                 error "Locked pages remain in cache, locked=$LOCKED"
9947         fi
9948
9949         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9950                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9951         fi
9952
9953         rm -f $DIR/$tfile
9954         echo "No pages locked after fsync"
9955
9956         reset_async
9957         return 0
9958 }
9959 run_test 118f "Simulate unrecoverable OSC side error =========="
9960
9961 test_118g() {
9962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9963
9964         reset_async
9965
9966         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9967         lctl set_param fail_loc=0x406
9968
9969         # simulate local -ENOMEM
9970         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9971         RC=$?
9972
9973         lctl set_param fail_loc=0
9974         if [[ $RC -eq 0 ]]; then
9975                 error "Must return error due to dropped pages, rc=$RC"
9976         fi
9977
9978         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9979         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9980         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9981                         grep -c writeback)
9982         if [[ $LOCKED -ne 0 ]]; then
9983                 error "Locked pages remain in cache, locked=$LOCKED"
9984         fi
9985
9986         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9987                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9988         fi
9989
9990         rm -f $DIR/$tfile
9991         echo "No pages locked after fsync"
9992
9993         reset_async
9994         return 0
9995 }
9996 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
9997
9998 test_118h() {
9999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10000         remote_ost_nodsh && skip "remote OST with nodsh"
10001
10002         reset_async
10003
10004         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10005         set_nodes_failloc "$(osts_nodes)" 0x20e
10006         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10007         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10008         RC=$?
10009
10010         set_nodes_failloc "$(osts_nodes)" 0
10011         if [[ $RC -eq 0 ]]; then
10012                 error "Must return error due to dropped pages, rc=$RC"
10013         fi
10014
10015         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10016         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10017         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10018                     grep -c writeback)
10019         if [[ $LOCKED -ne 0 ]]; then
10020                 error "Locked pages remain in cache, locked=$LOCKED"
10021         fi
10022
10023         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10024                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10025         fi
10026
10027         rm -f $DIR/$tfile
10028         echo "No pages locked after fsync"
10029
10030         return 0
10031 }
10032 run_test 118h "Verify timeout in handling recoverables errors  =========="
10033
10034 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10035
10036 test_118i() {
10037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10038         remote_ost_nodsh && skip "remote OST with nodsh"
10039
10040         reset_async
10041
10042         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10043         set_nodes_failloc "$(osts_nodes)" 0x20e
10044
10045         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10046         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10047         PID=$!
10048         sleep 5
10049         set_nodes_failloc "$(osts_nodes)" 0
10050
10051         wait $PID
10052         RC=$?
10053         if [[ $RC -ne 0 ]]; then
10054                 error "got error, but should be not, rc=$RC"
10055         fi
10056
10057         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10058         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10059         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10060         if [[ $LOCKED -ne 0 ]]; then
10061                 error "Locked pages remain in cache, locked=$LOCKED"
10062         fi
10063
10064         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10065                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10066         fi
10067
10068         rm -f $DIR/$tfile
10069         echo "No pages locked after fsync"
10070
10071         return 0
10072 }
10073 run_test 118i "Fix error before timeout in recoverable error  =========="
10074
10075 [ "$SLOW" = "no" ] && set_resend_count 4
10076
10077 test_118j() {
10078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10079         remote_ost_nodsh && skip "remote OST with nodsh"
10080
10081         reset_async
10082
10083         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
10084         set_nodes_failloc "$(osts_nodes)" 0x220
10085
10086         # return -EIO from OST
10087         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10088         RC=$?
10089         set_nodes_failloc "$(osts_nodes)" 0x0
10090         if [[ $RC -eq 0 ]]; then
10091                 error "Must return error due to dropped pages, rc=$RC"
10092         fi
10093
10094         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10095         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10096         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10097         if [[ $LOCKED -ne 0 ]]; then
10098                 error "Locked pages remain in cache, locked=$LOCKED"
10099         fi
10100
10101         # in recoverable error on OST we want resend and stay until it finished
10102         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10103                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10104         fi
10105
10106         rm -f $DIR/$tfile
10107         echo "No pages locked after fsync"
10108
10109         return 0
10110 }
10111 run_test 118j "Simulate unrecoverable OST side error =========="
10112
10113 test_118k()
10114 {
10115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10116         remote_ost_nodsh && skip "remote OSTs with nodsh"
10117
10118         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10119         set_nodes_failloc "$(osts_nodes)" 0x20e
10120         test_mkdir $DIR/$tdir
10121
10122         for ((i=0;i<10;i++)); do
10123                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
10124                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
10125                 SLEEPPID=$!
10126                 sleep 0.500s
10127                 kill $SLEEPPID
10128                 wait $SLEEPPID
10129         done
10130
10131         set_nodes_failloc "$(osts_nodes)" 0
10132         rm -rf $DIR/$tdir
10133 }
10134 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
10135
10136 test_118l() # LU-646
10137 {
10138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10139
10140         test_mkdir $DIR/$tdir
10141         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
10142         rm -rf $DIR/$tdir
10143 }
10144 run_test 118l "fsync dir"
10145
10146 test_118m() # LU-3066
10147 {
10148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10149
10150         test_mkdir $DIR/$tdir
10151         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
10152         rm -rf $DIR/$tdir
10153 }
10154 run_test 118m "fdatasync dir ========="
10155
10156 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10157
10158 test_118n()
10159 {
10160         local begin
10161         local end
10162
10163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10164         remote_ost_nodsh && skip "remote OSTs with nodsh"
10165
10166         # Sleep to avoid a cached response.
10167         #define OBD_STATFS_CACHE_SECONDS 1
10168         sleep 2
10169
10170         # Inject a 10 second delay in the OST_STATFS handler.
10171         #define OBD_FAIL_OST_STATFS_DELAY 0x242
10172         set_nodes_failloc "$(osts_nodes)" 0x242
10173
10174         begin=$SECONDS
10175         stat --file-system $MOUNT > /dev/null
10176         end=$SECONDS
10177
10178         set_nodes_failloc "$(osts_nodes)" 0
10179
10180         if ((end - begin > 20)); then
10181             error "statfs took $((end - begin)) seconds, expected 10"
10182         fi
10183 }
10184 run_test 118n "statfs() sends OST_STATFS requests in parallel"
10185
10186 test_119a() # bug 11737
10187 {
10188         BSIZE=$((512 * 1024))
10189         directio write $DIR/$tfile 0 1 $BSIZE
10190         # We ask to read two blocks, which is more than a file size.
10191         # directio will indicate an error when requested and actual
10192         # sizes aren't equeal (a normal situation in this case) and
10193         # print actual read amount.
10194         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
10195         if [ "$NOB" != "$BSIZE" ]; then
10196                 error "read $NOB bytes instead of $BSIZE"
10197         fi
10198         rm -f $DIR/$tfile
10199 }
10200 run_test 119a "Short directIO read must return actual read amount"
10201
10202 test_119b() # bug 11737
10203 {
10204         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10205
10206         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
10207         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
10208         sync
10209         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
10210                 error "direct read failed"
10211         rm -f $DIR/$tfile
10212 }
10213 run_test 119b "Sparse directIO read must return actual read amount"
10214
10215 test_119c() # bug 13099
10216 {
10217         BSIZE=1048576
10218         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
10219         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
10220         rm -f $DIR/$tfile
10221 }
10222 run_test 119c "Testing for direct read hitting hole"
10223
10224 test_119d() # bug 15950
10225 {
10226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10227
10228         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
10229         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
10230         BSIZE=1048576
10231         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
10232         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
10233         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
10234         lctl set_param fail_loc=0x40d
10235         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
10236         pid_dio=$!
10237         sleep 1
10238         cat $DIR/$tfile > /dev/null &
10239         lctl set_param fail_loc=0
10240         pid_reads=$!
10241         wait $pid_dio
10242         log "the DIO writes have completed, now wait for the reads (should not block very long)"
10243         sleep 2
10244         [ -n "`ps h -p $pid_reads -o comm`" ] && \
10245         error "the read rpcs have not completed in 2s"
10246         rm -f $DIR/$tfile
10247         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
10248 }
10249 run_test 119d "The DIO path should try to send a new rpc once one is completed"
10250
10251 test_120a() {
10252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10253         remote_mds_nodsh && skip "remote MDS with nodsh"
10254         test_mkdir -i0 -c1 $DIR/$tdir
10255         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10256                 skip_env "no early lock cancel on server"
10257
10258         lru_resize_disable mdc
10259         lru_resize_disable osc
10260         cancel_lru_locks mdc
10261         # asynchronous object destroy at MDT could cause bl ast to client
10262         cancel_lru_locks osc
10263
10264         stat $DIR/$tdir > /dev/null
10265         can1=$(do_facet mds1 \
10266                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10267                awk '/ldlm_cancel/ {print $2}')
10268         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10269                awk '/ldlm_bl_callback/ {print $2}')
10270         test_mkdir -i0 -c1 $DIR/$tdir/d1
10271         can2=$(do_facet mds1 \
10272                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10273                awk '/ldlm_cancel/ {print $2}')
10274         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10275                awk '/ldlm_bl_callback/ {print $2}')
10276         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10277         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10278         lru_resize_enable mdc
10279         lru_resize_enable osc
10280 }
10281 run_test 120a "Early Lock Cancel: mkdir test"
10282
10283 test_120b() {
10284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10285         remote_mds_nodsh && skip "remote MDS with nodsh"
10286         test_mkdir $DIR/$tdir
10287         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10288                 skip_env "no early lock cancel on server"
10289
10290         lru_resize_disable mdc
10291         lru_resize_disable osc
10292         cancel_lru_locks mdc
10293         stat $DIR/$tdir > /dev/null
10294         can1=$(do_facet $SINGLEMDS \
10295                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10296                awk '/ldlm_cancel/ {print $2}')
10297         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10298                awk '/ldlm_bl_callback/ {print $2}')
10299         touch $DIR/$tdir/f1
10300         can2=$(do_facet $SINGLEMDS \
10301                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10302                awk '/ldlm_cancel/ {print $2}')
10303         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10304                awk '/ldlm_bl_callback/ {print $2}')
10305         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10306         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10307         lru_resize_enable mdc
10308         lru_resize_enable osc
10309 }
10310 run_test 120b "Early Lock Cancel: create test"
10311
10312 test_120c() {
10313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10314         remote_mds_nodsh && skip "remote MDS with nodsh"
10315         test_mkdir -i0 -c1 $DIR/$tdir
10316         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10317                 skip "no early lock cancel on server"
10318
10319         lru_resize_disable mdc
10320         lru_resize_disable osc
10321         test_mkdir -i0 -c1 $DIR/$tdir/d1
10322         test_mkdir -i0 -c1 $DIR/$tdir/d2
10323         touch $DIR/$tdir/d1/f1
10324         cancel_lru_locks mdc
10325         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
10326         can1=$(do_facet mds1 \
10327                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10328                awk '/ldlm_cancel/ {print $2}')
10329         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10330                awk '/ldlm_bl_callback/ {print $2}')
10331         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10332         can2=$(do_facet mds1 \
10333                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10334                awk '/ldlm_cancel/ {print $2}')
10335         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10336                awk '/ldlm_bl_callback/ {print $2}')
10337         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10338         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10339         lru_resize_enable mdc
10340         lru_resize_enable osc
10341 }
10342 run_test 120c "Early Lock Cancel: link test"
10343
10344 test_120d() {
10345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10346         remote_mds_nodsh && skip "remote MDS with nodsh"
10347         test_mkdir -i0 -c1 $DIR/$tdir
10348         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10349                 skip_env "no early lock cancel on server"
10350
10351         lru_resize_disable mdc
10352         lru_resize_disable osc
10353         touch $DIR/$tdir
10354         cancel_lru_locks mdc
10355         stat $DIR/$tdir > /dev/null
10356         can1=$(do_facet mds1 \
10357                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10358                awk '/ldlm_cancel/ {print $2}')
10359         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10360                awk '/ldlm_bl_callback/ {print $2}')
10361         chmod a+x $DIR/$tdir
10362         can2=$(do_facet mds1 \
10363                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10364                awk '/ldlm_cancel/ {print $2}')
10365         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10366                awk '/ldlm_bl_callback/ {print $2}')
10367         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10368         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10369         lru_resize_enable mdc
10370         lru_resize_enable osc
10371 }
10372 run_test 120d "Early Lock Cancel: setattr test"
10373
10374 test_120e() {
10375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10376         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10377                 skip_env "no early lock cancel on server"
10378         remote_mds_nodsh && skip "remote MDS with nodsh"
10379
10380         local dlmtrace_set=false
10381
10382         test_mkdir -i0 -c1 $DIR/$tdir
10383         lru_resize_disable mdc
10384         lru_resize_disable osc
10385         ! $LCTL get_param debug | grep -q dlmtrace &&
10386                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
10387         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
10388         cancel_lru_locks mdc
10389         cancel_lru_locks osc
10390         dd if=$DIR/$tdir/f1 of=/dev/null
10391         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
10392         # XXX client can not do early lock cancel of OST lock
10393         # during unlink (LU-4206), so cancel osc lock now.
10394         sleep 2
10395         cancel_lru_locks osc
10396         can1=$(do_facet mds1 \
10397                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10398                awk '/ldlm_cancel/ {print $2}')
10399         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10400                awk '/ldlm_bl_callback/ {print $2}')
10401         unlink $DIR/$tdir/f1
10402         sleep 5
10403         can2=$(do_facet mds1 \
10404                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10405                awk '/ldlm_cancel/ {print $2}')
10406         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10407                awk '/ldlm_bl_callback/ {print $2}')
10408         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
10409                 $LCTL dk $TMP/cancel.debug.txt
10410         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
10411                 $LCTL dk $TMP/blocking.debug.txt
10412         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
10413         lru_resize_enable mdc
10414         lru_resize_enable osc
10415 }
10416 run_test 120e "Early Lock Cancel: unlink test"
10417
10418 test_120f() {
10419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10420         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10421                 skip_env "no early lock cancel on server"
10422         remote_mds_nodsh && skip "remote MDS with nodsh"
10423
10424         test_mkdir -i0 -c1 $DIR/$tdir
10425         lru_resize_disable mdc
10426         lru_resize_disable osc
10427         test_mkdir -i0 -c1 $DIR/$tdir/d1
10428         test_mkdir -i0 -c1 $DIR/$tdir/d2
10429         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
10430         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
10431         cancel_lru_locks mdc
10432         cancel_lru_locks osc
10433         dd if=$DIR/$tdir/d1/f1 of=/dev/null
10434         dd if=$DIR/$tdir/d2/f2 of=/dev/null
10435         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
10436         # XXX client can not do early lock cancel of OST lock
10437         # during rename (LU-4206), so cancel osc lock now.
10438         sleep 2
10439         cancel_lru_locks osc
10440         can1=$(do_facet mds1 \
10441                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10442                awk '/ldlm_cancel/ {print $2}')
10443         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10444                awk '/ldlm_bl_callback/ {print $2}')
10445         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10446         sleep 5
10447         can2=$(do_facet mds1 \
10448                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10449                awk '/ldlm_cancel/ {print $2}')
10450         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10451                awk '/ldlm_bl_callback/ {print $2}')
10452         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10453         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10454         lru_resize_enable mdc
10455         lru_resize_enable osc
10456 }
10457 run_test 120f "Early Lock Cancel: rename test"
10458
10459 test_120g() {
10460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10461         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10462                 skip_env "no early lock cancel on server"
10463         remote_mds_nodsh && skip "remote MDS with nodsh"
10464
10465         lru_resize_disable mdc
10466         lru_resize_disable osc
10467         count=10000
10468         echo create $count files
10469         test_mkdir $DIR/$tdir
10470         cancel_lru_locks mdc
10471         cancel_lru_locks osc
10472         t0=$(date +%s)
10473
10474         can0=$(do_facet $SINGLEMDS \
10475                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10476                awk '/ldlm_cancel/ {print $2}')
10477         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10478                awk '/ldlm_bl_callback/ {print $2}')
10479         createmany -o $DIR/$tdir/f $count
10480         sync
10481         can1=$(do_facet $SINGLEMDS \
10482                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10483                awk '/ldlm_cancel/ {print $2}')
10484         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10485                awk '/ldlm_bl_callback/ {print $2}')
10486         t1=$(date +%s)
10487         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
10488         echo rm $count files
10489         rm -r $DIR/$tdir
10490         sync
10491         can2=$(do_facet $SINGLEMDS \
10492                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10493                awk '/ldlm_cancel/ {print $2}')
10494         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10495                awk '/ldlm_bl_callback/ {print $2}')
10496         t2=$(date +%s)
10497         echo total: $count removes in $((t2-t1))
10498         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
10499         sleep 2
10500         # wait for commitment of removal
10501         lru_resize_enable mdc
10502         lru_resize_enable osc
10503 }
10504 run_test 120g "Early Lock Cancel: performance test"
10505
10506 test_121() { #bug #10589
10507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10508
10509         rm -rf $DIR/$tfile
10510         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
10511 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
10512         lctl set_param fail_loc=0x310
10513         cancel_lru_locks osc > /dev/null
10514         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
10515         lctl set_param fail_loc=0
10516         [[ $reads -eq $writes ]] ||
10517                 error "read $reads blocks, must be $writes blocks"
10518 }
10519 run_test 121 "read cancel race ========="
10520
10521 test_123a() { # was test 123, statahead(bug 11401)
10522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10523
10524         SLOWOK=0
10525         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
10526                 log "testing UP system. Performance may be lower than expected."
10527                 SLOWOK=1
10528         fi
10529
10530         rm -rf $DIR/$tdir
10531         test_mkdir $DIR/$tdir
10532         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
10533         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
10534         MULT=10
10535         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
10536                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
10537
10538                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10539                 lctl set_param -n llite.*.statahead_max 0
10540                 lctl get_param llite.*.statahead_max
10541                 cancel_lru_locks mdc
10542                 cancel_lru_locks osc
10543                 stime=`date +%s`
10544                 time ls -l $DIR/$tdir | wc -l
10545                 etime=`date +%s`
10546                 delta=$((etime - stime))
10547                 log "ls $i files without statahead: $delta sec"
10548                 lctl set_param llite.*.statahead_max=$max
10549
10550                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10551                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
10552                 cancel_lru_locks mdc
10553                 cancel_lru_locks osc
10554                 stime=`date +%s`
10555                 time ls -l $DIR/$tdir | wc -l
10556                 etime=`date +%s`
10557                 delta_sa=$((etime - stime))
10558                 log "ls $i files with statahead: $delta_sa sec"
10559                 lctl get_param -n llite.*.statahead_stats
10560                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10561
10562                 [[ $swrong -lt $ewrong ]] &&
10563                         log "statahead was stopped, maybe too many locks held!"
10564                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
10565
10566                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10567                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10568                     lctl set_param -n llite.*.statahead_max 0
10569                     lctl get_param llite.*.statahead_max
10570                     cancel_lru_locks mdc
10571                     cancel_lru_locks osc
10572                     stime=`date +%s`
10573                     time ls -l $DIR/$tdir | wc -l
10574                     etime=`date +%s`
10575                     delta=$((etime - stime))
10576                     log "ls $i files again without statahead: $delta sec"
10577                     lctl set_param llite.*.statahead_max=$max
10578                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10579                         if [  $SLOWOK -eq 0 ]; then
10580                                 error "ls $i files is slower with statahead!"
10581                         else
10582                                 log "ls $i files is slower with statahead!"
10583                         fi
10584                         break
10585                     fi
10586                 fi
10587
10588                 [ $delta -gt 20 ] && break
10589                 [ $delta -gt 8 ] && MULT=$((50 / delta))
10590                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
10591         done
10592         log "ls done"
10593
10594         stime=`date +%s`
10595         rm -r $DIR/$tdir
10596         sync
10597         etime=`date +%s`
10598         delta=$((etime - stime))
10599         log "rm -r $DIR/$tdir/: $delta seconds"
10600         log "rm done"
10601         lctl get_param -n llite.*.statahead_stats
10602 }
10603 run_test 123a "verify statahead work"
10604
10605 test_123b () { # statahead(bug 15027)
10606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10607
10608         test_mkdir $DIR/$tdir
10609         createmany -o $DIR/$tdir/$tfile-%d 1000
10610
10611         cancel_lru_locks mdc
10612         cancel_lru_locks osc
10613
10614 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
10615         lctl set_param fail_loc=0x80000803
10616         ls -lR $DIR/$tdir > /dev/null
10617         log "ls done"
10618         lctl set_param fail_loc=0x0
10619         lctl get_param -n llite.*.statahead_stats
10620         rm -r $DIR/$tdir
10621         sync
10622
10623 }
10624 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
10625
10626 test_124a() {
10627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10628         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10629                 skip_env "no lru resize on server"
10630
10631         local NR=2000
10632
10633         test_mkdir $DIR/$tdir
10634
10635         log "create $NR files at $DIR/$tdir"
10636         createmany -o $DIR/$tdir/f $NR ||
10637                 error "failed to create $NR files in $DIR/$tdir"
10638
10639         cancel_lru_locks mdc
10640         ls -l $DIR/$tdir > /dev/null
10641
10642         local NSDIR=""
10643         local LRU_SIZE=0
10644         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
10645                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
10646                 LRU_SIZE=$($LCTL get_param -n $PARAM)
10647                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
10648                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
10649                         log "NSDIR=$NSDIR"
10650                         log "NS=$(basename $NSDIR)"
10651                         break
10652                 fi
10653         done
10654
10655         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
10656                 skip "Not enough cached locks created!"
10657         fi
10658         log "LRU=$LRU_SIZE"
10659
10660         local SLEEP=30
10661
10662         # We know that lru resize allows one client to hold $LIMIT locks
10663         # for 10h. After that locks begin to be killed by client.
10664         local MAX_HRS=10
10665         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
10666         log "LIMIT=$LIMIT"
10667         if [ $LIMIT -lt $LRU_SIZE ]; then
10668                 skip "Limit is too small $LIMIT"
10669         fi
10670
10671         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
10672         # killing locks. Some time was spent for creating locks. This means
10673         # that up to the moment of sleep finish we must have killed some of
10674         # them (10-100 locks). This depends on how fast ther were created.
10675         # Many of them were touched in almost the same moment and thus will
10676         # be killed in groups.
10677         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
10678
10679         # Use $LRU_SIZE_B here to take into account real number of locks
10680         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
10681         local LRU_SIZE_B=$LRU_SIZE
10682         log "LVF=$LVF"
10683         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
10684         log "OLD_LVF=$OLD_LVF"
10685         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
10686
10687         # Let's make sure that we really have some margin. Client checks
10688         # cached locks every 10 sec.
10689         SLEEP=$((SLEEP+20))
10690         log "Sleep ${SLEEP} sec"
10691         local SEC=0
10692         while ((SEC<$SLEEP)); do
10693                 echo -n "..."
10694                 sleep 5
10695                 SEC=$((SEC+5))
10696                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
10697                 echo -n "$LRU_SIZE"
10698         done
10699         echo ""
10700         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
10701         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
10702
10703         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
10704                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
10705                 unlinkmany $DIR/$tdir/f $NR
10706                 return
10707         }
10708
10709         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
10710         log "unlink $NR files at $DIR/$tdir"
10711         unlinkmany $DIR/$tdir/f $NR
10712 }
10713 run_test 124a "lru resize ======================================="
10714
10715 get_max_pool_limit()
10716 {
10717         local limit=$($LCTL get_param \
10718                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
10719         local max=0
10720         for l in $limit; do
10721                 if [[ $l -gt $max ]]; then
10722                         max=$l
10723                 fi
10724         done
10725         echo $max
10726 }
10727
10728 test_124b() {
10729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10730         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10731                 skip_env "no lru resize on server"
10732
10733         LIMIT=$(get_max_pool_limit)
10734
10735         NR=$(($(default_lru_size)*20))
10736         if [[ $NR -gt $LIMIT ]]; then
10737                 log "Limit lock number by $LIMIT locks"
10738                 NR=$LIMIT
10739         fi
10740
10741         IFree=$(mdsrate_inodes_available)
10742         if [ $IFree -lt $NR ]; then
10743                 log "Limit lock number by $IFree inodes"
10744                 NR=$IFree
10745         fi
10746
10747         lru_resize_disable mdc
10748         test_mkdir -p $DIR/$tdir/disable_lru_resize
10749
10750         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
10751         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
10752         cancel_lru_locks mdc
10753         stime=`date +%s`
10754         PID=""
10755         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10756         PID="$PID $!"
10757         sleep 2
10758         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10759         PID="$PID $!"
10760         sleep 2
10761         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10762         PID="$PID $!"
10763         wait $PID
10764         etime=`date +%s`
10765         nolruresize_delta=$((etime-stime))
10766         log "ls -la time: $nolruresize_delta seconds"
10767         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10768         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
10769
10770         lru_resize_enable mdc
10771         test_mkdir -p $DIR/$tdir/enable_lru_resize
10772
10773         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
10774         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
10775         cancel_lru_locks mdc
10776         stime=`date +%s`
10777         PID=""
10778         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10779         PID="$PID $!"
10780         sleep 2
10781         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10782         PID="$PID $!"
10783         sleep 2
10784         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10785         PID="$PID $!"
10786         wait $PID
10787         etime=`date +%s`
10788         lruresize_delta=$((etime-stime))
10789         log "ls -la time: $lruresize_delta seconds"
10790         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10791
10792         if [ $lruresize_delta -gt $nolruresize_delta ]; then
10793                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
10794         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
10795                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
10796         else
10797                 log "lru resize performs the same with no lru resize"
10798         fi
10799         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
10800 }
10801 run_test 124b "lru resize (performance test) ======================="
10802
10803 test_124c() {
10804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10805         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10806                 skip_env "no lru resize on server"
10807
10808         # cache ununsed locks on client
10809         local nr=100
10810         cancel_lru_locks mdc
10811         test_mkdir $DIR/$tdir
10812         createmany -o $DIR/$tdir/f $nr ||
10813                 error "failed to create $nr files in $DIR/$tdir"
10814         ls -l $DIR/$tdir > /dev/null
10815
10816         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
10817         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
10818         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
10819         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
10820         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
10821
10822         # set lru_max_age to 1 sec
10823         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
10824         echo "sleep $((recalc_p * 2)) seconds..."
10825         sleep $((recalc_p * 2))
10826
10827         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
10828         # restore lru_max_age
10829         $LCTL set_param -n $nsdir.lru_max_age $max_age
10830         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
10831         unlinkmany $DIR/$tdir/f $nr
10832 }
10833 run_test 124c "LRUR cancel very aged locks"
10834
10835 test_125() { # 13358
10836         $LCTL get_param -n llite.*.client_type | grep -q local ||
10837                 skip "must run as local client"
10838         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
10839                 skip_env "must have acl enabled"
10840         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
10841
10842         test_mkdir $DIR/$tdir
10843         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
10844         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
10845         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
10846 }
10847 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
10848
10849 test_126() { # bug 12829/13455
10850         $GSS && skip_env "must run as gss disabled"
10851         $LCTL get_param -n llite.*.client_type | grep -q local ||
10852                 skip "must run as local client"
10853         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
10854
10855         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
10856         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
10857         rm -f $DIR/$tfile
10858         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
10859 }
10860 run_test 126 "check that the fsgid provided by the client is taken into account"
10861
10862 test_127a() { # bug 15521
10863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10864
10865         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
10866         $LCTL set_param osc.*.stats=0
10867         FSIZE=$((2048 * 1024))
10868         dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
10869         cancel_lru_locks osc
10870         dd if=$DIR/$tfile of=/dev/null bs=$FSIZE
10871
10872         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/${tfile}.tmp
10873         while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
10874                 echo "got $COUNT $NAME"
10875                 [ ! $MIN ] && error "Missing min value for $NAME proc entry"
10876                 eval $NAME=$COUNT || error "Wrong proc format"
10877
10878                 case $NAME in
10879                         read_bytes|write_bytes)
10880                         [ $MIN -lt 4096 ] && error "min is too small: $MIN"
10881                         [ $MIN -gt $FSIZE ] && error "min is too big: $MIN"
10882                         [ $MAX -lt 4096 ] && error "max is too small: $MAX"
10883                         [ $MAX -gt $FSIZE ] && error "max is too big: $MAX"
10884                         [ $SUM -ne $FSIZE ] && error "sum is wrong: $SUM"
10885                         [ $SUMSQ -lt $(((FSIZE /4096) * (4096 * 4096))) ] &&
10886                                 error "sumsquare is too small: $SUMSQ"
10887                         [ $SUMSQ -gt $((FSIZE * FSIZE)) ] &&
10888                                 error "sumsquare is too big: $SUMSQ"
10889                         ;;
10890                         *) ;;
10891                 esac
10892         done < $DIR/${tfile}.tmp
10893
10894         #check that we actually got some stats
10895         [ "$read_bytes" ] || error "Missing read_bytes stats"
10896         [ "$write_bytes" ] || error "Missing write_bytes stats"
10897         [ "$read_bytes" != 0 ] || error "no read done"
10898         [ "$write_bytes" != 0 ] || error "no write done"
10899 }
10900 run_test 127a "verify the client stats are sane"
10901
10902 test_127b() { # bug LU-333
10903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10904         local name count samp unit min max sum sumsq
10905
10906         $LCTL set_param llite.*.stats=0
10907
10908         # perform 2 reads and writes so MAX is different from SUM.
10909         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10910         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10911         cancel_lru_locks osc
10912         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10913         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10914
10915         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
10916         while read name count samp unit min max sum sumsq; do
10917                 echo "got $count $name"
10918                 eval $name=$count || error "Wrong proc format"
10919
10920                 case $name in
10921                 read_bytes)
10922                         [ $count -ne 2 ] && error "count is not 2: $count"
10923                         [ $min -ne $PAGE_SIZE ] &&
10924                                 error "min is not $PAGE_SIZE: $min"
10925                         [ $max -ne $PAGE_SIZE ] &&
10926                                 error "max is incorrect: $max"
10927                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10928                                 error "sum is wrong: $sum"
10929                         ;;
10930                 write_bytes)
10931                         [ $count -ne 2 ] && error "count is not 2: $count"
10932                         [ $min -ne $PAGE_SIZE ] &&
10933                                 error "min is not $PAGE_SIZE: $min"
10934                         [ $max -ne $PAGE_SIZE ] &&
10935                                 error "max is incorrect: $max"
10936                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10937                                 error "sum is wrong: $sum"
10938                         ;;
10939                 *) ;;
10940                 esac
10941         done < $TMP/$tfile.tmp
10942
10943         #check that we actually got some stats
10944         [ "$read_bytes" ] || error "Missing read_bytes stats"
10945         [ "$write_bytes" ] || error "Missing write_bytes stats"
10946         [ "$read_bytes" != 0 ] || error "no read done"
10947         [ "$write_bytes" != 0 ] || error "no write done"
10948
10949         rm -f $TMP/${tfile}.tmp
10950 }
10951 run_test 127b "verify the llite client stats are sane"
10952
10953 test_128() { # bug 15212
10954         touch $DIR/$tfile
10955         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
10956                 find $DIR/$tfile
10957                 find $DIR/$tfile
10958         EOF
10959
10960         result=$(grep error $TMP/$tfile.log)
10961         rm -f $DIR/$tfile $TMP/$tfile.log
10962         [ -z "$result" ] ||
10963                 error "consecutive find's under interactive lfs failed"
10964 }
10965 run_test 128 "interactive lfs for 2 consecutive find's"
10966
10967 set_dir_limits () {
10968         local mntdev
10969         local canondev
10970         local node
10971
10972         local ldproc=/proc/fs/ldiskfs
10973         local facets=$(get_facets MDS)
10974
10975         for facet in ${facets//,/ }; do
10976                 canondev=$(ldiskfs_canon \
10977                            *.$(convert_facet2label $facet).mntdev $facet)
10978                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
10979                         ldproc=/sys/fs/ldiskfs
10980                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
10981                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
10982         done
10983 }
10984
10985 check_mds_dmesg() {
10986         local facets=$(get_facets MDS)
10987         for facet in ${facets//,/ }; do
10988                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
10989         done
10990         return 1
10991 }
10992
10993 test_129() {
10994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10995         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
10996                 skip "Need MDS version with at least 2.5.56"
10997         if [ "$mds1_FSTYPE" != ldiskfs ]; then
10998                 skip_env "ldiskfs only test"
10999         fi
11000         remote_mds_nodsh && skip "remote MDS with nodsh"
11001
11002         local ENOSPC=28
11003         local EFBIG=27
11004         local has_warning=false
11005
11006         rm -rf $DIR/$tdir
11007         mkdir -p $DIR/$tdir
11008
11009         # block size of mds1
11010         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
11011         set_dir_limits $maxsize $maxsize
11012         local dirsize=$(stat -c%s "$DIR/$tdir")
11013         local nfiles=0
11014         while [[ $dirsize -le $maxsize ]]; do
11015                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
11016                 rc=$?
11017                 if ! $has_warning; then
11018                         check_mds_dmesg '"is approaching"' && has_warning=true
11019                 fi
11020                 # check two errors:
11021                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
11022                 # EFBIG for previous versions included in ldiskfs series
11023                 if [ $rc -eq $EFBIG ] || [ $rc -eq $ENOSPC ]; then
11024                         set_dir_limits 0 0
11025                         echo "return code $rc received as expected"
11026
11027                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
11028                                 error_exit "create failed w/o dir size limit"
11029
11030                         check_mds_dmesg '"has reached"' ||
11031                                 error_exit "reached message should be output"
11032
11033                         [ $has_warning = "false" ] &&
11034                                 error_exit "warning message should be output"
11035
11036                         dirsize=$(stat -c%s "$DIR/$tdir")
11037
11038                         [[ $dirsize -ge $maxsize ]] && return 0
11039                         error_exit "current dir size $dirsize, " \
11040                                    "previous limit $maxsize"
11041                 elif [ $rc -ne 0 ]; then
11042                         set_dir_limits 0 0
11043                         error_exit "return $rc received instead of expected " \
11044                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
11045                 fi
11046                 nfiles=$((nfiles + 1))
11047                 dirsize=$(stat -c%s "$DIR/$tdir")
11048         done
11049
11050         set_dir_limits 0 0
11051         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
11052 }
11053 run_test 129 "test directory size limit ========================"
11054
11055 OLDIFS="$IFS"
11056 cleanup_130() {
11057         trap 0
11058         IFS="$OLDIFS"
11059 }
11060
11061 test_130a() {
11062         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11063         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11064
11065         trap cleanup_130 EXIT RETURN
11066
11067         local fm_file=$DIR/$tfile
11068         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
11069         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
11070                 error "dd failed for $fm_file"
11071
11072         # LU-1795: test filefrag/FIEMAP once, even if unsupported
11073         filefrag -ves $fm_file
11074         RC=$?
11075         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11076                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11077         [ $RC != 0 ] && error "filefrag $fm_file failed"
11078
11079         filefrag_op=$(filefrag -ve -k $fm_file |
11080                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11081         lun=$($LFS getstripe -i $fm_file)
11082
11083         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
11084         IFS=$'\n'
11085         tot_len=0
11086         for line in $filefrag_op
11087         do
11088                 frag_lun=`echo $line | cut -d: -f5`
11089                 ext_len=`echo $line | cut -d: -f4`
11090                 if (( $frag_lun != $lun )); then
11091                         cleanup_130
11092                         error "FIEMAP on 1-stripe file($fm_file) failed"
11093                         return
11094                 fi
11095                 (( tot_len += ext_len ))
11096         done
11097
11098         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
11099                 cleanup_130
11100                 error "FIEMAP on 1-stripe file($fm_file) failed;"
11101                 return
11102         fi
11103
11104         cleanup_130
11105
11106         echo "FIEMAP on single striped file succeeded"
11107 }
11108 run_test 130a "FIEMAP (1-stripe file)"
11109
11110 test_130b() {
11111         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11112
11113         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11114         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11115
11116         trap cleanup_130 EXIT RETURN
11117
11118         local fm_file=$DIR/$tfile
11119         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11120                         error "setstripe on $fm_file"
11121         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11122                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11123
11124         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
11125                 error "dd failed on $fm_file"
11126
11127         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11128         filefrag_op=$(filefrag -ve -k $fm_file |
11129                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11130
11131         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11132                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11133
11134         IFS=$'\n'
11135         tot_len=0
11136         num_luns=1
11137         for line in $filefrag_op
11138         do
11139                 frag_lun=$(echo $line | cut -d: -f5 |
11140                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11141                 ext_len=$(echo $line | cut -d: -f4)
11142                 if (( $frag_lun != $last_lun )); then
11143                         if (( tot_len != 1024 )); then
11144                                 cleanup_130
11145                                 error "FIEMAP on $fm_file failed; returned " \
11146                                 "len $tot_len for OST $last_lun instead of 1024"
11147                                 return
11148                         else
11149                                 (( num_luns += 1 ))
11150                                 tot_len=0
11151                         fi
11152                 fi
11153                 (( tot_len += ext_len ))
11154                 last_lun=$frag_lun
11155         done
11156         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
11157                 cleanup_130
11158                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11159                         "luns or wrong len for OST $last_lun"
11160                 return
11161         fi
11162
11163         cleanup_130
11164
11165         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
11166 }
11167 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
11168
11169 test_130c() {
11170         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11171
11172         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11173         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11174
11175         trap cleanup_130 EXIT RETURN
11176
11177         local fm_file=$DIR/$tfile
11178         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
11179         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11180                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11181
11182         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
11183                         error "dd failed on $fm_file"
11184
11185         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11186         filefrag_op=$(filefrag -ve -k $fm_file |
11187                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11188
11189         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11190                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11191
11192         IFS=$'\n'
11193         tot_len=0
11194         num_luns=1
11195         for line in $filefrag_op
11196         do
11197                 frag_lun=$(echo $line | cut -d: -f5 |
11198                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11199                 ext_len=$(echo $line | cut -d: -f4)
11200                 if (( $frag_lun != $last_lun )); then
11201                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
11202                         if (( logical != 512 )); then
11203                                 cleanup_130
11204                                 error "FIEMAP on $fm_file failed; returned " \
11205                                 "logical start for lun $logical instead of 512"
11206                                 return
11207                         fi
11208                         if (( tot_len != 512 )); then
11209                                 cleanup_130
11210                                 error "FIEMAP on $fm_file failed; returned " \
11211                                 "len $tot_len for OST $last_lun instead of 1024"
11212                                 return
11213                         else
11214                                 (( num_luns += 1 ))
11215                                 tot_len=0
11216                         fi
11217                 fi
11218                 (( tot_len += ext_len ))
11219                 last_lun=$frag_lun
11220         done
11221         if (( num_luns != 2 || tot_len != 512 )); then
11222                 cleanup_130
11223                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11224                         "luns or wrong len for OST $last_lun"
11225                 return
11226         fi
11227
11228         cleanup_130
11229
11230         echo "FIEMAP on 2-stripe file with hole succeeded"
11231 }
11232 run_test 130c "FIEMAP (2-stripe file with hole)"
11233
11234 test_130d() {
11235         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
11236
11237         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11238         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11239
11240         trap cleanup_130 EXIT RETURN
11241
11242         local fm_file=$DIR/$tfile
11243         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11244                         error "setstripe on $fm_file"
11245         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11246                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11247
11248         local actual_stripe_count=$($LFS getstripe -c $fm_file)
11249         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
11250                 error "dd failed on $fm_file"
11251
11252         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11253         filefrag_op=$(filefrag -ve -k $fm_file |
11254                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11255
11256         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11257                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11258
11259         IFS=$'\n'
11260         tot_len=0
11261         num_luns=1
11262         for line in $filefrag_op
11263         do
11264                 frag_lun=$(echo $line | cut -d: -f5 |
11265                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11266                 ext_len=$(echo $line | cut -d: -f4)
11267                 if (( $frag_lun != $last_lun )); then
11268                         if (( tot_len != 1024 )); then
11269                                 cleanup_130
11270                                 error "FIEMAP on $fm_file failed; returned " \
11271                                 "len $tot_len for OST $last_lun instead of 1024"
11272                                 return
11273                         else
11274                                 (( num_luns += 1 ))
11275                                 tot_len=0
11276                         fi
11277                 fi
11278                 (( tot_len += ext_len ))
11279                 last_lun=$frag_lun
11280         done
11281         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
11282                 cleanup_130
11283                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11284                         "luns or wrong len for OST $last_lun"
11285                 return
11286         fi
11287
11288         cleanup_130
11289
11290         echo "FIEMAP on N-stripe file succeeded"
11291 }
11292 run_test 130d "FIEMAP (N-stripe file)"
11293
11294 test_130e() {
11295         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11296
11297         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11298         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11299
11300         trap cleanup_130 EXIT RETURN
11301
11302         local fm_file=$DIR/$tfile
11303         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
11304         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11305                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11306
11307         NUM_BLKS=512
11308         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
11309         for ((i = 0; i < $NUM_BLKS; i++))
11310         do
11311                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
11312         done
11313
11314         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11315         filefrag_op=$(filefrag -ve -k $fm_file |
11316                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11317
11318         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11319                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11320
11321         IFS=$'\n'
11322         tot_len=0
11323         num_luns=1
11324         for line in $filefrag_op
11325         do
11326                 frag_lun=$(echo $line | cut -d: -f5 |
11327                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11328                 ext_len=$(echo $line | cut -d: -f4)
11329                 if (( $frag_lun != $last_lun )); then
11330                         if (( tot_len != $EXPECTED_LEN )); then
11331                                 cleanup_130
11332                                 error "FIEMAP on $fm_file failed; returned " \
11333                                 "len $tot_len for OST $last_lun instead " \
11334                                 "of $EXPECTED_LEN"
11335                                 return
11336                         else
11337                                 (( num_luns += 1 ))
11338                                 tot_len=0
11339                         fi
11340                 fi
11341                 (( tot_len += ext_len ))
11342                 last_lun=$frag_lun
11343         done
11344         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
11345                 cleanup_130
11346                 error "FIEMAP on $fm_file failed; returned wrong number " \
11347                         "of luns or wrong len for OST $last_lun"
11348                 return
11349         fi
11350
11351         cleanup_130
11352
11353         echo "FIEMAP with continuation calls succeeded"
11354 }
11355 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
11356
11357 test_130f() {
11358         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11359         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11360
11361         local fm_file=$DIR/$tfile
11362         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
11363                 error "multiop create with lov_delay_create on $fm_file"
11364
11365         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11366         filefrag_extents=$(filefrag -vek $fm_file |
11367                            awk '/extents? found/ { print $2 }')
11368         if [[ "$filefrag_extents" != "0" ]]; then
11369                 error "FIEMAP on $fm_file failed; " \
11370                       "returned $filefrag_extents expected 0"
11371         fi
11372
11373         rm -f $fm_file
11374 }
11375 run_test 130f "FIEMAP (unstriped file)"
11376
11377 # Test for writev/readv
11378 test_131a() {
11379         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
11380                 error "writev test failed"
11381         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
11382                 error "readv failed"
11383         rm -f $DIR/$tfile
11384 }
11385 run_test 131a "test iov's crossing stripe boundary for writev/readv"
11386
11387 test_131b() {
11388         local fsize=$((524288 + 1048576 + 1572864))
11389         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
11390                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11391                         error "append writev test failed"
11392
11393         ((fsize += 1572864 + 1048576))
11394         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
11395                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11396                         error "append writev test failed"
11397         rm -f $DIR/$tfile
11398 }
11399 run_test 131b "test append writev"
11400
11401 test_131c() {
11402         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
11403         error "NOT PASS"
11404 }
11405 run_test 131c "test read/write on file w/o objects"
11406
11407 test_131d() {
11408         rwv -f $DIR/$tfile -w -n 1 1572864
11409         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
11410         if [ "$NOB" != 1572864 ]; then
11411                 error "Short read filed: read $NOB bytes instead of 1572864"
11412         fi
11413         rm -f $DIR/$tfile
11414 }
11415 run_test 131d "test short read"
11416
11417 test_131e() {
11418         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
11419         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
11420         error "read hitting hole failed"
11421         rm -f $DIR/$tfile
11422 }
11423 run_test 131e "test read hitting hole"
11424
11425 check_stats() {
11426         local facet=$1
11427         local op=$2
11428         local want=${3:-0}
11429         local res
11430
11431         case $facet in
11432         mds*) res=$(do_facet $facet \
11433                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
11434                  ;;
11435         ost*) res=$(do_facet $facet \
11436                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
11437                  ;;
11438         *) error "Wrong facet '$facet'" ;;
11439         esac
11440         [ "$res" ] || error "The counter for $op on $facet was not incremented"
11441         # if the argument $3 is zero, it means any stat increment is ok.
11442         if [[ $want -gt 0 ]]; then
11443                 local count=$(echo $res | awk '{ print $2 }')
11444                 [[ $count -ne $want ]] &&
11445                         error "The $op counter on $facet is $count, not $want"
11446         fi
11447 }
11448
11449 test_133a() {
11450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11451         remote_ost_nodsh && skip "remote OST with nodsh"
11452         remote_mds_nodsh && skip "remote MDS with nodsh"
11453         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11454                 skip_env "MDS doesn't support rename stats"
11455
11456         local testdir=$DIR/${tdir}/stats_testdir
11457
11458         mkdir -p $DIR/${tdir}
11459
11460         # clear stats.
11461         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11462         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11463
11464         # verify mdt stats first.
11465         mkdir ${testdir} || error "mkdir failed"
11466         check_stats $SINGLEMDS "mkdir" 1
11467         touch ${testdir}/${tfile} || error "touch failed"
11468         check_stats $SINGLEMDS "open" 1
11469         check_stats $SINGLEMDS "close" 1
11470         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
11471                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
11472                 check_stats $SINGLEMDS "mknod" 2
11473         }
11474         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
11475         check_stats $SINGLEMDS "unlink" 1
11476         rm -f ${testdir}/${tfile} || error "file remove failed"
11477         check_stats $SINGLEMDS "unlink" 2
11478
11479         # remove working dir and check mdt stats again.
11480         rmdir ${testdir} || error "rmdir failed"
11481         check_stats $SINGLEMDS "rmdir" 1
11482
11483         local testdir1=$DIR/${tdir}/stats_testdir1
11484         mkdir -p ${testdir}
11485         mkdir -p ${testdir1}
11486         touch ${testdir1}/test1
11487         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
11488         check_stats $SINGLEMDS "crossdir_rename" 1
11489
11490         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
11491         check_stats $SINGLEMDS "samedir_rename" 1
11492
11493         rm -rf $DIR/${tdir}
11494 }
11495 run_test 133a "Verifying MDT stats ========================================"
11496
11497 test_133b() {
11498         local res
11499
11500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11501         remote_ost_nodsh && skip "remote OST with nodsh"
11502         remote_mds_nodsh && skip "remote MDS with nodsh"
11503
11504         local testdir=$DIR/${tdir}/stats_testdir
11505
11506         mkdir -p ${testdir} || error "mkdir failed"
11507         touch ${testdir}/${tfile} || error "touch failed"
11508         cancel_lru_locks mdc
11509
11510         # clear stats.
11511         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11512         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11513
11514         # extra mdt stats verification.
11515         chmod 444 ${testdir}/${tfile} || error "chmod failed"
11516         check_stats $SINGLEMDS "setattr" 1
11517         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11518         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
11519         then            # LU-1740
11520                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
11521                 check_stats $SINGLEMDS "getattr" 1
11522         fi
11523         rm -rf $DIR/${tdir}
11524
11525         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
11526         # so the check below is not reliable
11527         [ $MDSCOUNT -eq 1 ] || return 0
11528
11529         # Sleep to avoid a cached response.
11530         #define OBD_STATFS_CACHE_SECONDS 1
11531         sleep 2
11532         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11533         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11534         $LFS df || error "lfs failed"
11535         check_stats $SINGLEMDS "statfs" 1
11536
11537         # check aggregated statfs (LU-10018)
11538         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
11539                 return 0
11540         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
11541                 return 0
11542         sleep 2
11543         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11544         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11545         df $DIR
11546         check_stats $SINGLEMDS "statfs" 1
11547
11548         # We want to check that the client didn't send OST_STATFS to
11549         # ost1 but the MDT also uses OST_STATFS for precreate. So some
11550         # extra care is needed here.
11551         if remote_mds; then
11552                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
11553                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
11554
11555                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
11556                 [ "$res" ] && error "OST got STATFS"
11557         fi
11558
11559         return 0
11560 }
11561 run_test 133b "Verifying extra MDT stats =================================="
11562
11563 test_133c() {
11564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11565         remote_ost_nodsh && skip "remote OST with nodsh"
11566         remote_mds_nodsh && skip "remote MDS with nodsh"
11567
11568         local testdir=$DIR/$tdir/stats_testdir
11569
11570         test_mkdir -p $testdir
11571
11572         # verify obdfilter stats.
11573         $LFS setstripe -c 1 -i 0 $testdir/$tfile
11574         sync
11575         cancel_lru_locks osc
11576         wait_delete_completed
11577
11578         # clear stats.
11579         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11580         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11581
11582         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
11583                 error "dd failed"
11584         sync
11585         cancel_lru_locks osc
11586         check_stats ost1 "write" 1
11587
11588         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
11589         check_stats ost1 "read" 1
11590
11591         > $testdir/$tfile || error "truncate failed"
11592         check_stats ost1 "punch" 1
11593
11594         rm -f $testdir/$tfile || error "file remove failed"
11595         wait_delete_completed
11596         check_stats ost1 "destroy" 1
11597
11598         rm -rf $DIR/$tdir
11599 }
11600 run_test 133c "Verifying OST stats ========================================"
11601
11602 order_2() {
11603         local value=$1
11604         local orig=$value
11605         local order=1
11606
11607         while [ $value -ge 2 ]; do
11608                 order=$((order*2))
11609                 value=$((value/2))
11610         done
11611
11612         if [ $orig -gt $order ]; then
11613                 order=$((order*2))
11614         fi
11615         echo $order
11616 }
11617
11618 size_in_KMGT() {
11619     local value=$1
11620     local size=('K' 'M' 'G' 'T');
11621     local i=0
11622     local size_string=$value
11623
11624     while [ $value -ge 1024 ]; do
11625         if [ $i -gt 3 ]; then
11626             #T is the biggest unit we get here, if that is bigger,
11627             #just return XXXT
11628             size_string=${value}T
11629             break
11630         fi
11631         value=$((value >> 10))
11632         if [ $value -lt 1024 ]; then
11633             size_string=${value}${size[$i]}
11634             break
11635         fi
11636         i=$((i + 1))
11637     done
11638
11639     echo $size_string
11640 }
11641
11642 get_rename_size() {
11643         local size=$1
11644         local context=${2:-.}
11645         local sample=$(do_facet $SINGLEMDS $LCTL \
11646                 get_param mdt.$FSNAME-MDT0000.rename_stats |
11647                 grep -A1 $context |
11648                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
11649         echo $sample
11650 }
11651
11652 test_133d() {
11653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11654         remote_ost_nodsh && skip "remote OST with nodsh"
11655         remote_mds_nodsh && skip "remote MDS with nodsh"
11656         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11657                 skip_env "MDS doesn't support rename stats"
11658
11659         local testdir1=$DIR/${tdir}/stats_testdir1
11660         local testdir2=$DIR/${tdir}/stats_testdir2
11661         mkdir -p $DIR/${tdir}
11662
11663         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11664
11665         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
11666         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
11667
11668         createmany -o $testdir1/test 512 || error "createmany failed"
11669
11670         # check samedir rename size
11671         mv ${testdir1}/test0 ${testdir1}/test_0
11672
11673         local testdir1_size=$(ls -l $DIR/${tdir} |
11674                 awk '/stats_testdir1/ {print $5}')
11675         local testdir2_size=$(ls -l $DIR/${tdir} |
11676                 awk '/stats_testdir2/ {print $5}')
11677
11678         testdir1_size=$(order_2 $testdir1_size)
11679         testdir2_size=$(order_2 $testdir2_size)
11680
11681         testdir1_size=$(size_in_KMGT $testdir1_size)
11682         testdir2_size=$(size_in_KMGT $testdir2_size)
11683
11684         echo "source rename dir size: ${testdir1_size}"
11685         echo "target rename dir size: ${testdir2_size}"
11686
11687         local cmd="do_facet $SINGLEMDS $LCTL "
11688         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
11689
11690         eval $cmd || error "$cmd failed"
11691         local samedir=$($cmd | grep 'same_dir')
11692         local same_sample=$(get_rename_size $testdir1_size)
11693         [ -z "$samedir" ] && error "samedir_rename_size count error"
11694         [[ $same_sample -eq 1 ]] ||
11695                 error "samedir_rename_size error $same_sample"
11696         echo "Check same dir rename stats success"
11697
11698         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11699
11700         # check crossdir rename size
11701         mv ${testdir1}/test_0 ${testdir2}/test_0
11702
11703         testdir1_size=$(ls -l $DIR/${tdir} |
11704                 awk '/stats_testdir1/ {print $5}')
11705         testdir2_size=$(ls -l $DIR/${tdir} |
11706                 awk '/stats_testdir2/ {print $5}')
11707
11708         testdir1_size=$(order_2 $testdir1_size)
11709         testdir2_size=$(order_2 $testdir2_size)
11710
11711         testdir1_size=$(size_in_KMGT $testdir1_size)
11712         testdir2_size=$(size_in_KMGT $testdir2_size)
11713
11714         echo "source rename dir size: ${testdir1_size}"
11715         echo "target rename dir size: ${testdir2_size}"
11716
11717         eval $cmd || error "$cmd failed"
11718         local crossdir=$($cmd | grep 'crossdir')
11719         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
11720         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
11721         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
11722         [[ $src_sample -eq 1 ]] ||
11723                 error "crossdir_rename_size error $src_sample"
11724         [[ $tgt_sample -eq 1 ]] ||
11725                 error "crossdir_rename_size error $tgt_sample"
11726         echo "Check cross dir rename stats success"
11727         rm -rf $DIR/${tdir}
11728 }
11729 run_test 133d "Verifying rename_stats ========================================"
11730
11731 test_133e() {
11732         remote_mds_nodsh && skip "remote MDS with nodsh"
11733         remote_ost_nodsh && skip "remote OST with nodsh"
11734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11735
11736         local testdir=$DIR/${tdir}/stats_testdir
11737         local ctr f0 f1 bs=32768 count=42 sum
11738
11739         mkdir -p ${testdir} || error "mkdir failed"
11740
11741         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
11742
11743         for ctr in {write,read}_bytes; do
11744                 sync
11745                 cancel_lru_locks osc
11746
11747                 do_facet ost1 $LCTL set_param -n \
11748                         "obdfilter.*.exports.clear=clear"
11749
11750                 if [ $ctr = write_bytes ]; then
11751                         f0=/dev/zero
11752                         f1=${testdir}/${tfile}
11753                 else
11754                         f0=${testdir}/${tfile}
11755                         f1=/dev/null
11756                 fi
11757
11758                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
11759                         error "dd failed"
11760                 sync
11761                 cancel_lru_locks osc
11762
11763                 sum=$(do_facet ost1 $LCTL get_param \
11764                         "obdfilter.*.exports.*.stats" |
11765                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
11766                                 $1 == ctr { sum += $7 }
11767                                 END { printf("%0.0f", sum) }')
11768
11769                 if ((sum != bs * count)); then
11770                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
11771                 fi
11772         done
11773
11774         rm -rf $DIR/${tdir}
11775 }
11776 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
11777
11778 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
11779
11780 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
11781 # not honor the -ignore_readdir_race option correctly. So we call
11782 # error_ignore() rather than error() in these cases. See LU-11152.
11783 error_133() {
11784         if (find --version; do_facet mds1 find --version) |
11785                 grep -q '\b4\.5\.1[1-4]\b'; then
11786                 error_ignore LU-11152 "$@"
11787         else
11788                 error "$@"
11789         fi
11790 }
11791
11792 test_133f() {
11793         # First without trusting modes.
11794         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
11795         echo "proc_dirs='$proc_dirs'"
11796         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
11797         find $proc_dirs -exec cat '{}' \; &> /dev/null
11798
11799         # Second verifying readability.
11800         $LCTL get_param -R '*' &> /dev/null
11801
11802         # Verifing writability with badarea_io.
11803         find $proc_dirs \
11804                 -ignore_readdir_race \
11805                 -type f \
11806                 -not -name force_lbug \
11807                 -not -name changelog_mask \
11808                 -exec badarea_io '{}' \; ||
11809                         error_133 "find $proc_dirs failed"
11810 }
11811 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
11812
11813 test_133g() {
11814         remote_mds_nodsh && skip "remote MDS with nodsh"
11815         remote_ost_nodsh && skip "remote OST with nodsh"
11816
11817         # eventually, this can also be replaced with "lctl get_param -R",
11818         # but not until that option is always available on the server
11819         local facet
11820         for facet in mds1 ost1; do
11821                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
11822                         skip_noexit "Too old lustre on $facet"
11823                 local facet_proc_dirs=$(do_facet $facet \
11824                                         \\\ls -d $proc_regexp 2>/dev/null)
11825                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11826                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11827                 do_facet $facet find $facet_proc_dirs \
11828                         ! -name req_history \
11829                         -exec cat '{}' \\\; &> /dev/null
11830
11831                 do_facet $facet find $facet_proc_dirs \
11832                         ! -name req_history \
11833                         -type f \
11834                         -exec cat '{}' \\\; &> /dev/null ||
11835                                 error "proc file read failed"
11836
11837                 do_facet $facet find $facet_proc_dirs \
11838                         -ignore_readdir_race \
11839                         -type f \
11840                         -not -name force_lbug \
11841                         -not -name changelog_mask \
11842                         -exec badarea_io '{}' \\\; ||
11843                                 error_133 "$facet find $facet_proc_dirs failed"
11844         done
11845
11846         # remount the FS in case writes/reads /proc break the FS
11847         cleanup || error "failed to unmount"
11848         setup || error "failed to setup"
11849         true
11850 }
11851 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
11852
11853 test_133h() {
11854         remote_mds_nodsh && skip "remote MDS with nodsh"
11855         remote_ost_nodsh && skip "remote OST with nodsh"
11856         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
11857                 skip "Need MDS version at least 2.9.54"
11858
11859         local facet
11860
11861         for facet in client mds1 ost1; do
11862                 local facet_proc_dirs=$(do_facet $facet \
11863                                         \\\ls -d $proc_regexp 2> /dev/null)
11864                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11865                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11866                 # Get the list of files that are missing the terminating newline
11867                 local missing=($(do_facet $facet \
11868                         find ${facet_proc_dirs} -type f \|              \
11869                                 while read F\; do                       \
11870                                         awk -v FS='\v' -v RS='\v\v'     \
11871                                         "'END { if(NR>0 &&              \
11872                                         \\\$NF !~ /.*\\\n\$/)           \
11873                                                 print FILENAME}'"       \
11874                                         '\$F'\;                         \
11875                                 done 2>/dev/null))
11876                 [ ${#missing[*]} -eq 0 ] ||
11877                         error "files do not end with newline: ${missing[*]}"
11878         done
11879 }
11880 run_test 133h "Proc files should end with newlines"
11881
11882 test_134a() {
11883         remote_mds_nodsh && skip "remote MDS with nodsh"
11884         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11885                 skip "Need MDS version at least 2.7.54"
11886
11887         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11888         cancel_lru_locks mdc
11889
11890         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11891         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11892         [ $unused -eq 0 ] || error "$unused locks are not cleared"
11893
11894         local nr=1000
11895         createmany -o $DIR/$tdir/f $nr ||
11896                 error "failed to create $nr files in $DIR/$tdir"
11897         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11898
11899         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
11900         do_facet mds1 $LCTL set_param fail_loc=0x327
11901         do_facet mds1 $LCTL set_param fail_val=500
11902         touch $DIR/$tdir/m
11903
11904         echo "sleep 10 seconds ..."
11905         sleep 10
11906         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
11907
11908         do_facet mds1 $LCTL set_param fail_loc=0
11909         do_facet mds1 $LCTL set_param fail_val=0
11910         [ $lck_cnt -lt $unused ] ||
11911                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
11912
11913         rm $DIR/$tdir/m
11914         unlinkmany $DIR/$tdir/f $nr
11915 }
11916 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
11917
11918 test_134b() {
11919         remote_mds_nodsh && skip "remote MDS with nodsh"
11920         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11921                 skip "Need MDS version at least 2.7.54"
11922
11923         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11924         cancel_lru_locks mdc
11925
11926         local low_wm=$(do_facet mds1 $LCTL get_param -n \
11927                         ldlm.lock_reclaim_threshold_mb)
11928         # disable reclaim temporarily
11929         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
11930
11931         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
11932         do_facet mds1 $LCTL set_param fail_loc=0x328
11933         do_facet mds1 $LCTL set_param fail_val=500
11934
11935         $LCTL set_param debug=+trace
11936
11937         local nr=600
11938         createmany -o $DIR/$tdir/f $nr &
11939         local create_pid=$!
11940
11941         echo "Sleep $TIMEOUT seconds ..."
11942         sleep $TIMEOUT
11943         if ! ps -p $create_pid  > /dev/null 2>&1; then
11944                 do_facet mds1 $LCTL set_param fail_loc=0
11945                 do_facet mds1 $LCTL set_param fail_val=0
11946                 do_facet mds1 $LCTL set_param \
11947                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
11948                 error "createmany finished incorrectly!"
11949         fi
11950         do_facet mds1 $LCTL set_param fail_loc=0
11951         do_facet mds1 $LCTL set_param fail_val=0
11952         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
11953         wait $create_pid || return 1
11954
11955         unlinkmany $DIR/$tdir/f $nr
11956 }
11957 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
11958
11959 test_140() { #bug-17379
11960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11961
11962         test_mkdir $DIR/$tdir
11963         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
11964         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
11965
11966         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
11967         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
11968         local i=0
11969         while i=$((i + 1)); do
11970                 test_mkdir $i
11971                 cd $i || error "Changing to $i"
11972                 ln -s ../stat stat || error "Creating stat symlink"
11973                 # Read the symlink until ELOOP present,
11974                 # not LBUGing the system is considered success,
11975                 # we didn't overrun the stack.
11976                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
11977                 if [ $ret -ne 0 ]; then
11978                         if [ $ret -eq 40 ]; then
11979                                 break  # -ELOOP
11980                         else
11981                                 error "Open stat symlink"
11982                                         return
11983                         fi
11984                 fi
11985         done
11986         i=$((i - 1))
11987         echo "The symlink depth = $i"
11988         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
11989                 error "Invalid symlink depth"
11990
11991         # Test recursive symlink
11992         ln -s symlink_self symlink_self
11993         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
11994         echo "open symlink_self returns $ret"
11995         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
11996 }
11997 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
11998
11999 test_150() {
12000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12001
12002         local TF="$TMP/$tfile"
12003
12004         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12005         cp $TF $DIR/$tfile
12006         cancel_lru_locks $OSC
12007         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
12008         remount_client $MOUNT
12009         df -P $MOUNT
12010         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
12011
12012         $TRUNCATE $TF 6000
12013         $TRUNCATE $DIR/$tfile 6000
12014         cancel_lru_locks $OSC
12015         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
12016
12017         echo "12345" >>$TF
12018         echo "12345" >>$DIR/$tfile
12019         cancel_lru_locks $OSC
12020         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
12021
12022         echo "12345" >>$TF
12023         echo "12345" >>$DIR/$tfile
12024         cancel_lru_locks $OSC
12025         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
12026
12027         rm -f $TF
12028         true
12029 }
12030 run_test 150 "truncate/append tests"
12031
12032 #LU-2902 roc_hit was not able to read all values from lproc
12033 function roc_hit_init() {
12034         local list=$(comma_list $(osts_nodes))
12035         local dir=$DIR/$tdir-check
12036         local file=$dir/$tfile
12037         local BEFORE
12038         local AFTER
12039         local idx
12040
12041         test_mkdir $dir
12042         #use setstripe to do a write to every ost
12043         for i in $(seq 0 $((OSTCOUNT-1))); do
12044                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
12045                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
12046                 idx=$(printf %04x $i)
12047                 BEFORE=$(get_osd_param $list *OST*$idx stats |
12048                         awk '$1 == "cache_access" {sum += $7}
12049                                 END { printf("%0.0f", sum) }')
12050
12051                 cancel_lru_locks osc
12052                 cat $file >/dev/null
12053
12054                 AFTER=$(get_osd_param $list *OST*$idx stats |
12055                         awk '$1 == "cache_access" {sum += $7}
12056                                 END { printf("%0.0f", sum) }')
12057
12058                 echo BEFORE:$BEFORE AFTER:$AFTER
12059                 if ! let "AFTER - BEFORE == 4"; then
12060                         rm -rf $dir
12061                         error "roc_hit is not safe to use"
12062                 fi
12063                 rm $file
12064         done
12065
12066         rm -rf $dir
12067 }
12068
12069 function roc_hit() {
12070         local list=$(comma_list $(osts_nodes))
12071         echo $(get_osd_param $list '' stats |
12072                 awk '$1 == "cache_hit" {sum += $7}
12073                         END { printf("%0.0f", sum) }')
12074 }
12075
12076 function set_cache() {
12077         local on=1
12078
12079         if [ "$2" == "off" ]; then
12080                 on=0;
12081         fi
12082         local list=$(comma_list $(osts_nodes))
12083         set_osd_param $list '' $1_cache_enable $on
12084
12085         cancel_lru_locks osc
12086 }
12087
12088 test_151() {
12089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12090         remote_ost_nodsh && skip "remote OST with nodsh"
12091
12092         local CPAGES=3
12093         local list=$(comma_list $(osts_nodes))
12094
12095         # check whether obdfilter is cache capable at all
12096         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
12097                 skip "not cache-capable obdfilter"
12098         fi
12099
12100         # check cache is enabled on all obdfilters
12101         if get_osd_param $list '' read_cache_enable | grep 0; then
12102                 skip "oss cache is disabled"
12103         fi
12104
12105         set_osd_param $list '' writethrough_cache_enable 1
12106
12107         # check write cache is enabled on all obdfilters
12108         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
12109                 skip "oss write cache is NOT enabled"
12110         fi
12111
12112         roc_hit_init
12113
12114         #define OBD_FAIL_OBD_NO_LRU  0x609
12115         do_nodes $list $LCTL set_param fail_loc=0x609
12116
12117         # pages should be in the case right after write
12118         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
12119                 error "dd failed"
12120
12121         local BEFORE=$(roc_hit)
12122         cancel_lru_locks osc
12123         cat $DIR/$tfile >/dev/null
12124         local AFTER=$(roc_hit)
12125
12126         do_nodes $list $LCTL set_param fail_loc=0
12127
12128         if ! let "AFTER - BEFORE == CPAGES"; then
12129                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12130         fi
12131
12132         # the following read invalidates the cache
12133         cancel_lru_locks osc
12134         set_osd_param $list '' read_cache_enable 0
12135         cat $DIR/$tfile >/dev/null
12136
12137         # now data shouldn't be found in the cache
12138         BEFORE=$(roc_hit)
12139         cancel_lru_locks osc
12140         cat $DIR/$tfile >/dev/null
12141         AFTER=$(roc_hit)
12142         if let "AFTER - BEFORE != 0"; then
12143                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12144         fi
12145
12146         set_osd_param $list '' read_cache_enable 1
12147         rm -f $DIR/$tfile
12148 }
12149 run_test 151 "test cache on oss and controls ==============================="
12150
12151 test_152() {
12152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12153
12154         local TF="$TMP/$tfile"
12155
12156         # simulate ENOMEM during write
12157 #define OBD_FAIL_OST_NOMEM      0x226
12158         lctl set_param fail_loc=0x80000226
12159         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12160         cp $TF $DIR/$tfile
12161         sync || error "sync failed"
12162         lctl set_param fail_loc=0
12163
12164         # discard client's cache
12165         cancel_lru_locks osc
12166
12167         # simulate ENOMEM during read
12168         lctl set_param fail_loc=0x80000226
12169         cmp $TF $DIR/$tfile || error "cmp failed"
12170         lctl set_param fail_loc=0
12171
12172         rm -f $TF
12173 }
12174 run_test 152 "test read/write with enomem ============================"
12175
12176 test_153() {
12177         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
12178 }
12179 run_test 153 "test if fdatasync does not crash ======================="
12180
12181 dot_lustre_fid_permission_check() {
12182         local fid=$1
12183         local ffid=$MOUNT/.lustre/fid/$fid
12184         local test_dir=$2
12185
12186         echo "stat fid $fid"
12187         stat $ffid > /dev/null || error "stat $ffid failed."
12188         echo "touch fid $fid"
12189         touch $ffid || error "touch $ffid failed."
12190         echo "write to fid $fid"
12191         cat /etc/hosts > $ffid || error "write $ffid failed."
12192         echo "read fid $fid"
12193         diff /etc/hosts $ffid || error "read $ffid failed."
12194         echo "append write to fid $fid"
12195         cat /etc/hosts >> $ffid || error "append write $ffid failed."
12196         echo "rename fid $fid"
12197         mv $ffid $test_dir/$tfile.1 &&
12198                 error "rename $ffid to $tfile.1 should fail."
12199         touch $test_dir/$tfile.1
12200         mv $test_dir/$tfile.1 $ffid &&
12201                 error "rename $tfile.1 to $ffid should fail."
12202         rm -f $test_dir/$tfile.1
12203         echo "truncate fid $fid"
12204         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
12205         echo "link fid $fid"
12206         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
12207         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
12208                 echo "setfacl fid $fid"
12209                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
12210                 echo "getfacl fid $fid"
12211                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
12212         fi
12213         echo "unlink fid $fid"
12214         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
12215         echo "mknod fid $fid"
12216         mknod $ffid c 1 3 && error "mknod $ffid should fail."
12217
12218         fid=[0xf00000400:0x1:0x0]
12219         ffid=$MOUNT/.lustre/fid/$fid
12220
12221         echo "stat non-exist fid $fid"
12222         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
12223         echo "write to non-exist fid $fid"
12224         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
12225         echo "link new fid $fid"
12226         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
12227
12228         mkdir -p $test_dir/$tdir
12229         touch $test_dir/$tdir/$tfile
12230         fid=$($LFS path2fid $test_dir/$tdir)
12231         rc=$?
12232         [ $rc -ne 0 ] &&
12233                 error "error: could not get fid for $test_dir/$dir/$tfile."
12234
12235         ffid=$MOUNT/.lustre/fid/$fid
12236
12237         echo "ls $fid"
12238         ls $ffid > /dev/null || error "ls $ffid failed."
12239         echo "touch $fid/$tfile.1"
12240         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
12241
12242         echo "touch $MOUNT/.lustre/fid/$tfile"
12243         touch $MOUNT/.lustre/fid/$tfile && \
12244                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
12245
12246         echo "setxattr to $MOUNT/.lustre/fid"
12247         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
12248
12249         echo "listxattr for $MOUNT/.lustre/fid"
12250         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
12251
12252         echo "delxattr from $MOUNT/.lustre/fid"
12253         setfattr -x trusted.name1 $MOUNT/.lustre/fid
12254
12255         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
12256         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
12257                 error "touch invalid fid should fail."
12258
12259         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
12260         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
12261                 error "touch non-normal fid should fail."
12262
12263         echo "rename $tdir to $MOUNT/.lustre/fid"
12264         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
12265                 error "rename to $MOUNT/.lustre/fid should fail."
12266
12267         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
12268         then            # LU-3547
12269                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
12270                 local new_obf_mode=777
12271
12272                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
12273                 chmod $new_obf_mode $DIR/.lustre/fid ||
12274                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
12275
12276                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
12277                 [ $obf_mode -eq $new_obf_mode ] ||
12278                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
12279
12280                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
12281                 chmod $old_obf_mode $DIR/.lustre/fid ||
12282                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
12283         fi
12284
12285         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
12286         fid=$($LFS path2fid $test_dir/$tfile-2)
12287
12288         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
12289         then # LU-5424
12290                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
12291                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
12292                         error "create lov data thru .lustre failed"
12293         fi
12294         echo "cp /etc/passwd $test_dir/$tfile-2"
12295         cp /etc/passwd $test_dir/$tfile-2 ||
12296                 error "copy to $test_dir/$tfile-2 failed."
12297         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
12298         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
12299                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
12300
12301         rm -rf $test_dir/tfile.lnk
12302         rm -rf $test_dir/$tfile-2
12303 }
12304
12305 test_154A() {
12306         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12307                 skip "Need MDS version at least 2.4.1"
12308
12309         local tf=$DIR/$tfile
12310         touch $tf
12311
12312         local fid=$($LFS path2fid $tf)
12313         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
12314
12315         # check that we get the same pathname back
12316         local found=$($LFS fid2path $MOUNT "$fid")
12317         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
12318         [ "$found" == "$tf" ] ||
12319                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
12320 }
12321 run_test 154A "lfs path2fid and fid2path basic checks"
12322
12323 test_154B() {
12324         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12325                 skip "Need MDS version at least 2.4.1"
12326
12327         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
12328         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
12329         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
12330         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
12331
12332         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
12333         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
12334
12335         # check that we get the same pathname
12336         echo "PFID: $PFID, name: $name"
12337         local FOUND=$($LFS fid2path $MOUNT "$PFID")
12338         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
12339         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
12340                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
12341
12342         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
12343 }
12344 run_test 154B "verify the ll_decode_linkea tool"
12345
12346 test_154a() {
12347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12348         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12349         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12350                 skip "Need MDS version at least 2.2.51"
12351         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12352
12353         cp /etc/hosts $DIR/$tfile
12354
12355         fid=$($LFS path2fid $DIR/$tfile)
12356         rc=$?
12357         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
12358
12359         dot_lustre_fid_permission_check "$fid" $DIR ||
12360                 error "dot lustre permission check $fid failed"
12361
12362         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
12363
12364         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
12365
12366         touch $MOUNT/.lustre/file &&
12367                 error "creation is not allowed under .lustre"
12368
12369         mkdir $MOUNT/.lustre/dir &&
12370                 error "mkdir is not allowed under .lustre"
12371
12372         rm -rf $DIR/$tfile
12373 }
12374 run_test 154a "Open-by-FID"
12375
12376 test_154b() {
12377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12378         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12379         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
12380         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12381                 skip "Need MDS version at least 2.2.51"
12382
12383         local remote_dir=$DIR/$tdir/remote_dir
12384         local MDTIDX=1
12385         local rc=0
12386
12387         mkdir -p $DIR/$tdir
12388         $LFS mkdir -i $MDTIDX $remote_dir ||
12389                 error "create remote directory failed"
12390
12391         cp /etc/hosts $remote_dir/$tfile
12392
12393         fid=$($LFS path2fid $remote_dir/$tfile)
12394         rc=$?
12395         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
12396
12397         dot_lustre_fid_permission_check "$fid" $remote_dir ||
12398                 error "dot lustre permission check $fid failed"
12399         rm -rf $DIR/$tdir
12400 }
12401 run_test 154b "Open-by-FID for remote directory"
12402
12403 test_154c() {
12404         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12405                 skip "Need MDS version at least 2.4.1"
12406
12407         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
12408         local FID1=$($LFS path2fid $DIR/$tfile.1)
12409         local FID2=$($LFS path2fid $DIR/$tfile.2)
12410         local FID3=$($LFS path2fid $DIR/$tfile.3)
12411
12412         local N=1
12413         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
12414                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
12415                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
12416                 local want=FID$N
12417                 [ "$FID" = "${!want}" ] ||
12418                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
12419                 N=$((N + 1))
12420         done
12421
12422         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
12423         do
12424                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
12425                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
12426                 N=$((N + 1))
12427         done
12428 }
12429 run_test 154c "lfs path2fid and fid2path multiple arguments"
12430
12431 test_154d() {
12432         remote_mds_nodsh && skip "remote MDS with nodsh"
12433         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
12434                 skip "Need MDS version at least 2.5.53"
12435
12436         if remote_mds; then
12437                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
12438         else
12439                 nid="0@lo"
12440         fi
12441         local proc_ofile="mdt.*.exports.'$nid'.open_files"
12442         local fd
12443         local cmd
12444
12445         rm -f $DIR/$tfile
12446         touch $DIR/$tfile
12447
12448         local fid=$($LFS path2fid $DIR/$tfile)
12449         # Open the file
12450         fd=$(free_fd)
12451         cmd="exec $fd<$DIR/$tfile"
12452         eval $cmd
12453         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
12454         echo "$fid_list" | grep "$fid"
12455         rc=$?
12456
12457         cmd="exec $fd>/dev/null"
12458         eval $cmd
12459         if [ $rc -ne 0 ]; then
12460                 error "FID $fid not found in open files list $fid_list"
12461         fi
12462 }
12463 run_test 154d "Verify open file fid"
12464
12465 test_154e()
12466 {
12467         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
12468                 skip "Need MDS version at least 2.6.50"
12469
12470         if ls -a $MOUNT | grep -q '^\.lustre$'; then
12471                 error ".lustre returned by readdir"
12472         fi
12473 }
12474 run_test 154e ".lustre is not returned by readdir"
12475
12476 test_154f() {
12477         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12478
12479         # create parent directory on a single MDT to avoid cross-MDT hardlinks
12480         test_mkdir -p -c1 $DIR/$tdir/d
12481         # test dirs inherit from its stripe
12482         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
12483         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
12484         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
12485         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
12486         touch $DIR/f
12487
12488         # get fid of parents
12489         local FID0=$($LFS path2fid $DIR/$tdir/d)
12490         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
12491         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
12492         local FID3=$($LFS path2fid $DIR)
12493
12494         # check that path2fid --parents returns expected <parent_fid>/name
12495         # 1) test for a directory (single parent)
12496         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
12497         [ "$parent" == "$FID0/foo1" ] ||
12498                 error "expected parent: $FID0/foo1, got: $parent"
12499
12500         # 2) test for a file with nlink > 1 (multiple parents)
12501         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
12502         echo "$parent" | grep -F "$FID1/$tfile" ||
12503                 error "$FID1/$tfile not returned in parent list"
12504         echo "$parent" | grep -F "$FID2/link" ||
12505                 error "$FID2/link not returned in parent list"
12506
12507         # 3) get parent by fid
12508         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
12509         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12510         echo "$parent" | grep -F "$FID1/$tfile" ||
12511                 error "$FID1/$tfile not returned in parent list (by fid)"
12512         echo "$parent" | grep -F "$FID2/link" ||
12513                 error "$FID2/link not returned in parent list (by fid)"
12514
12515         # 4) test for entry in root directory
12516         parent=$($LFS path2fid --parents $DIR/f)
12517         echo "$parent" | grep -F "$FID3/f" ||
12518                 error "$FID3/f not returned in parent list"
12519
12520         # 5) test it on root directory
12521         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
12522                 error "$MOUNT should not have parents"
12523
12524         # enable xattr caching and check that linkea is correctly updated
12525         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12526         save_lustre_params client "llite.*.xattr_cache" > $save
12527         lctl set_param llite.*.xattr_cache 1
12528
12529         # 6.1) linkea update on rename
12530         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
12531
12532         # get parents by fid
12533         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12534         # foo1 should no longer be returned in parent list
12535         echo "$parent" | grep -F "$FID1" &&
12536                 error "$FID1 should no longer be in parent list"
12537         # the new path should appear
12538         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
12539                 error "$FID2/$tfile.moved is not in parent list"
12540
12541         # 6.2) linkea update on unlink
12542         rm -f $DIR/$tdir/d/foo2/link
12543         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12544         # foo2/link should no longer be returned in parent list
12545         echo "$parent" | grep -F "$FID2/link" &&
12546                 error "$FID2/link should no longer be in parent list"
12547         true
12548
12549         rm -f $DIR/f
12550         restore_lustre_params < $save
12551         rm -f $save
12552 }
12553 run_test 154f "get parent fids by reading link ea"
12554
12555 test_154g()
12556 {
12557         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12558         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
12559            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
12560                 skip "Need MDS version at least 2.6.92"
12561
12562         mkdir -p $DIR/$tdir
12563         llapi_fid_test -d $DIR/$tdir
12564 }
12565 run_test 154g "various llapi FID tests"
12566
12567 test_155_small_load() {
12568     local temp=$TMP/$tfile
12569     local file=$DIR/$tfile
12570
12571     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
12572         error "dd of=$temp bs=6096 count=1 failed"
12573     cp $temp $file
12574     cancel_lru_locks $OSC
12575     cmp $temp $file || error "$temp $file differ"
12576
12577     $TRUNCATE $temp 6000
12578     $TRUNCATE $file 6000
12579     cmp $temp $file || error "$temp $file differ (truncate1)"
12580
12581     echo "12345" >>$temp
12582     echo "12345" >>$file
12583     cmp $temp $file || error "$temp $file differ (append1)"
12584
12585     echo "12345" >>$temp
12586     echo "12345" >>$file
12587     cmp $temp $file || error "$temp $file differ (append2)"
12588
12589     rm -f $temp $file
12590     true
12591 }
12592
12593 test_155_big_load() {
12594         remote_ost_nodsh && skip "remote OST with nodsh"
12595
12596         local temp=$TMP/$tfile
12597         local file=$DIR/$tfile
12598
12599         free_min_max
12600         local cache_size=$(do_facet ost$((MAXI+1)) \
12601                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
12602         local large_file_size=$((cache_size * 2))
12603
12604         echo "OSS cache size: $cache_size KB"
12605         echo "Large file size: $large_file_size KB"
12606
12607         [ $MAXV -le $large_file_size ] &&
12608                 skip_env "max available OST size needs > $large_file_size KB"
12609
12610         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
12611
12612         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
12613                 error "dd of=$temp bs=$large_file_size count=1k failed"
12614         cp $temp $file
12615         ls -lh $temp $file
12616         cancel_lru_locks osc
12617         cmp $temp $file || error "$temp $file differ"
12618
12619         rm -f $temp $file
12620         true
12621 }
12622
12623 save_writethrough() {
12624         local facets=$(get_facets OST)
12625
12626         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
12627 }
12628
12629 test_155a() {
12630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12631
12632         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12633
12634         save_writethrough $p
12635
12636         set_cache read on
12637         set_cache writethrough on
12638         test_155_small_load
12639         restore_lustre_params < $p
12640         rm -f $p
12641 }
12642 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
12643
12644 test_155b() {
12645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12646
12647         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12648
12649         save_writethrough $p
12650
12651         set_cache read on
12652         set_cache writethrough off
12653         test_155_small_load
12654         restore_lustre_params < $p
12655         rm -f $p
12656 }
12657 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
12658
12659 test_155c() {
12660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12661
12662         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12663
12664         save_writethrough $p
12665
12666         set_cache read off
12667         set_cache writethrough on
12668         test_155_small_load
12669         restore_lustre_params < $p
12670         rm -f $p
12671 }
12672 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
12673
12674 test_155d() {
12675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12676
12677         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12678
12679         save_writethrough $p
12680
12681         set_cache read off
12682         set_cache writethrough off
12683         test_155_small_load
12684         restore_lustre_params < $p
12685         rm -f $p
12686 }
12687 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
12688
12689 test_155e() {
12690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12691
12692         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12693
12694         save_writethrough $p
12695
12696         set_cache read on
12697         set_cache writethrough on
12698         test_155_big_load
12699         restore_lustre_params < $p
12700         rm -f $p
12701 }
12702 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
12703
12704 test_155f() {
12705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12706
12707         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12708
12709         save_writethrough $p
12710
12711         set_cache read on
12712         set_cache writethrough off
12713         test_155_big_load
12714         restore_lustre_params < $p
12715         rm -f $p
12716 }
12717 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
12718
12719 test_155g() {
12720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12721
12722         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12723
12724         save_writethrough $p
12725
12726         set_cache read off
12727         set_cache writethrough on
12728         test_155_big_load
12729         restore_lustre_params < $p
12730         rm -f $p
12731 }
12732 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
12733
12734 test_155h() {
12735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12736
12737         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12738
12739         save_writethrough $p
12740
12741         set_cache read off
12742         set_cache writethrough off
12743         test_155_big_load
12744         restore_lustre_params < $p
12745         rm -f $p
12746 }
12747 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
12748
12749 test_156() {
12750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12751         remote_ost_nodsh && skip "remote OST with nodsh"
12752         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
12753                 skip "stats not implemented on old servers"
12754         [ "$ost1_FSTYPE" = "zfs" ] &&
12755                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
12756
12757         local CPAGES=3
12758         local BEFORE
12759         local AFTER
12760         local file="$DIR/$tfile"
12761         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12762
12763         save_writethrough $p
12764         roc_hit_init
12765
12766         log "Turn on read and write cache"
12767         set_cache read on
12768         set_cache writethrough on
12769
12770         log "Write data and read it back."
12771         log "Read should be satisfied from the cache."
12772         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12773         BEFORE=$(roc_hit)
12774         cancel_lru_locks osc
12775         cat $file >/dev/null
12776         AFTER=$(roc_hit)
12777         if ! let "AFTER - BEFORE == CPAGES"; then
12778                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12779         else
12780                 log "cache hits:: before: $BEFORE, after: $AFTER"
12781         fi
12782
12783         log "Read again; it should be satisfied from the cache."
12784         BEFORE=$AFTER
12785         cancel_lru_locks osc
12786         cat $file >/dev/null
12787         AFTER=$(roc_hit)
12788         if ! let "AFTER - BEFORE == CPAGES"; then
12789                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12790         else
12791                 log "cache hits:: before: $BEFORE, after: $AFTER"
12792         fi
12793
12794         log "Turn off the read cache and turn on the write cache"
12795         set_cache read off
12796         set_cache writethrough on
12797
12798         log "Read again; it should be satisfied from the cache."
12799         BEFORE=$(roc_hit)
12800         cancel_lru_locks osc
12801         cat $file >/dev/null
12802         AFTER=$(roc_hit)
12803         if ! let "AFTER - BEFORE == CPAGES"; then
12804                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12805         else
12806                 log "cache hits:: before: $BEFORE, after: $AFTER"
12807         fi
12808
12809         log "Read again; it should not be satisfied from the cache."
12810         BEFORE=$AFTER
12811         cancel_lru_locks osc
12812         cat $file >/dev/null
12813         AFTER=$(roc_hit)
12814         if ! let "AFTER - BEFORE == 0"; then
12815                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12816         else
12817                 log "cache hits:: before: $BEFORE, after: $AFTER"
12818         fi
12819
12820         log "Write data and read it back."
12821         log "Read should be satisfied from the cache."
12822         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12823         BEFORE=$(roc_hit)
12824         cancel_lru_locks osc
12825         cat $file >/dev/null
12826         AFTER=$(roc_hit)
12827         if ! let "AFTER - BEFORE == CPAGES"; then
12828                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12829         else
12830                 log "cache hits:: before: $BEFORE, after: $AFTER"
12831         fi
12832
12833         log "Read again; it should not be satisfied from the cache."
12834         BEFORE=$AFTER
12835         cancel_lru_locks osc
12836         cat $file >/dev/null
12837         AFTER=$(roc_hit)
12838         if ! let "AFTER - BEFORE == 0"; then
12839                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12840         else
12841                 log "cache hits:: before: $BEFORE, after: $AFTER"
12842         fi
12843
12844         log "Turn off read and write cache"
12845         set_cache read off
12846         set_cache writethrough off
12847
12848         log "Write data and read it back"
12849         log "It should not be satisfied from the cache."
12850         rm -f $file
12851         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12852         cancel_lru_locks osc
12853         BEFORE=$(roc_hit)
12854         cat $file >/dev/null
12855         AFTER=$(roc_hit)
12856         if ! let "AFTER - BEFORE == 0"; then
12857                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12858         else
12859                 log "cache hits:: before: $BEFORE, after: $AFTER"
12860         fi
12861
12862         log "Turn on the read cache and turn off the write cache"
12863         set_cache read on
12864         set_cache writethrough off
12865
12866         log "Write data and read it back"
12867         log "It should not be satisfied from the cache."
12868         rm -f $file
12869         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12870         BEFORE=$(roc_hit)
12871         cancel_lru_locks osc
12872         cat $file >/dev/null
12873         AFTER=$(roc_hit)
12874         if ! let "AFTER - BEFORE == 0"; then
12875                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12876         else
12877                 log "cache hits:: before: $BEFORE, after: $AFTER"
12878         fi
12879
12880         log "Read again; it should be satisfied from the cache."
12881         BEFORE=$(roc_hit)
12882         cancel_lru_locks osc
12883         cat $file >/dev/null
12884         AFTER=$(roc_hit)
12885         if ! let "AFTER - BEFORE == CPAGES"; then
12886                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12887         else
12888                 log "cache hits:: before: $BEFORE, after: $AFTER"
12889         fi
12890
12891         restore_lustre_params < $p
12892         rm -f $p $file
12893 }
12894 run_test 156 "Verification of tunables"
12895
12896 test_160a() {
12897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12898         remote_mds_nodsh && skip "remote MDS with nodsh"
12899         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12900                 skip "Need MDS version at least 2.2.0"
12901
12902         changelog_register || error "changelog_register failed"
12903         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12904         changelog_users $SINGLEMDS | grep -q $cl_user ||
12905                 error "User $cl_user not found in changelog_users"
12906
12907         # change something
12908         test_mkdir -p $DIR/$tdir/pics/2008/zachy
12909         changelog_clear 0 || error "changelog_clear failed"
12910         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
12911         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
12912         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
12913         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
12914         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
12915         rm $DIR/$tdir/pics/desktop.jpg
12916
12917         changelog_dump | tail -10
12918
12919         echo "verifying changelog mask"
12920         changelog_chmask "-MKDIR"
12921         changelog_chmask "-CLOSE"
12922
12923         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
12924         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
12925
12926         changelog_chmask "+MKDIR"
12927         changelog_chmask "+CLOSE"
12928
12929         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
12930         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
12931
12932         changelog_dump | tail -10
12933         MKDIRS=$(changelog_dump | grep -c "MKDIR")
12934         CLOSES=$(changelog_dump | grep -c "CLOSE")
12935         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
12936         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
12937
12938         # verify contents
12939         echo "verifying target fid"
12940         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
12941         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
12942         [ "$fidc" == "$fidf" ] ||
12943                 error "changelog '$tfile' fid $fidc != file fid $fidf"
12944         echo "verifying parent fid"
12945         # The FID returned from the Changelog may be the directory shard on
12946         # a different MDT, and not the FID returned by path2fid on the parent.
12947         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
12948         # since this is what will matter when recreating this file in the tree.
12949         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
12950         local pathp=$($LFS fid2path $MOUNT "$fidp")
12951         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
12952                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
12953
12954         echo "getting records for $cl_user"
12955         changelog_users $SINGLEMDS
12956         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
12957         local nclr=3
12958         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
12959                 error "changelog_clear failed"
12960         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
12961         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
12962         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
12963                 error "user index expect $user_rec1 + $nclr != $user_rec2"
12964
12965         local min0_rec=$(changelog_users $SINGLEMDS |
12966                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
12967         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
12968                           awk '{ print $1; exit; }')
12969
12970         changelog_dump | tail -n 5
12971         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
12972         [ $first_rec == $((min0_rec + 1)) ] ||
12973                 error "first index should be $min0_rec + 1 not $first_rec"
12974
12975         # LU-3446 changelog index reset on MDT restart
12976         local cur_rec1=$(changelog_users $SINGLEMDS |
12977                          awk '/^current.index:/ { print $NF }')
12978         changelog_clear 0 ||
12979                 error "clear all changelog records for $cl_user failed"
12980         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
12981         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
12982                 error "Fail to start $SINGLEMDS"
12983         local cur_rec2=$(changelog_users $SINGLEMDS |
12984                          awk '/^current.index:/ { print $NF }')
12985         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
12986         [ $cur_rec1 == $cur_rec2 ] ||
12987                 error "current index should be $cur_rec1 not $cur_rec2"
12988
12989         echo "verifying users from this test are deregistered"
12990         changelog_deregister || error "changelog_deregister failed"
12991         changelog_users $SINGLEMDS | grep -q $cl_user &&
12992                 error "User '$cl_user' still in changelog_users"
12993
12994         # lctl get_param -n mdd.*.changelog_users
12995         # current index: 144
12996         # ID    index (idle seconds)
12997         # cl3   144 (2)
12998         if ! changelog_users $SINGLEMDS | grep "^cl"; then
12999                 # this is the normal case where all users were deregistered
13000                 # make sure no new records are added when no users are present
13001                 local last_rec1=$(changelog_users $SINGLEMDS |
13002                                   awk '/^current.index:/ { print $NF }')
13003                 touch $DIR/$tdir/chloe
13004                 local last_rec2=$(changelog_users $SINGLEMDS |
13005                                   awk '/^current.index:/ { print $NF }')
13006                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
13007                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
13008         else
13009                 # any changelog users must be leftovers from a previous test
13010                 changelog_users $SINGLEMDS
13011                 echo "other changelog users; can't verify off"
13012         fi
13013 }
13014 run_test 160a "changelog sanity"
13015
13016 test_160b() { # LU-3587
13017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13018         remote_mds_nodsh && skip "remote MDS with nodsh"
13019         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13020                 skip "Need MDS version at least 2.2.0"
13021
13022         changelog_register || error "changelog_register failed"
13023         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13024         changelog_users $SINGLEMDS | grep -q $cl_user ||
13025                 error "User '$cl_user' not found in changelog_users"
13026
13027         local longname1=$(str_repeat a 255)
13028         local longname2=$(str_repeat b 255)
13029
13030         cd $DIR
13031         echo "creating very long named file"
13032         touch $longname1 || error "create of '$longname1' failed"
13033         echo "renaming very long named file"
13034         mv $longname1 $longname2
13035
13036         changelog_dump | grep RENME | tail -n 5
13037         rm -f $longname2
13038 }
13039 run_test 160b "Verify that very long rename doesn't crash in changelog"
13040
13041 test_160c() {
13042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13043         remote_mds_nodsh && skip "remote MDS with nodsh"
13044
13045         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
13046                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
13047                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
13048                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
13049
13050         local rc=0
13051
13052         # Registration step
13053         changelog_register || error "changelog_register failed"
13054
13055         rm -rf $DIR/$tdir
13056         mkdir -p $DIR/$tdir
13057         $MCREATE $DIR/$tdir/foo_160c
13058         changelog_chmask "-TRUNC"
13059         $TRUNCATE $DIR/$tdir/foo_160c 200
13060         changelog_chmask "+TRUNC"
13061         $TRUNCATE $DIR/$tdir/foo_160c 199
13062         changelog_dump | tail -n 5
13063         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
13064         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
13065 }
13066 run_test 160c "verify that changelog log catch the truncate event"
13067
13068 test_160d() {
13069         remote_mds_nodsh && skip "remote MDS with nodsh"
13070         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13072         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
13073                 skip "Need MDS version at least 2.7.60"
13074
13075         # Registration step
13076         changelog_register || error "changelog_register failed"
13077
13078         mkdir -p $DIR/$tdir/migrate_dir
13079         changelog_clear 0 || error "changelog_clear failed"
13080
13081         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
13082         changelog_dump | tail -n 5
13083         local migrates=$(changelog_dump | grep -c "MIGRT")
13084         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
13085 }
13086 run_test 160d "verify that changelog log catch the migrate event"
13087
13088 test_160e() {
13089         remote_mds_nodsh && skip "remote MDS with nodsh"
13090
13091         # Create a user
13092         changelog_register || error "changelog_register failed"
13093
13094         # Delete a future user (expect fail)
13095         local MDT0=$(facet_svc $SINGLEMDS)
13096         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
13097         local rc=$?
13098
13099         if [ $rc -eq 0 ]; then
13100                 error "Deleted non-existant user cl77"
13101         elif [ $rc -ne 2 ]; then
13102                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
13103         fi
13104
13105         # Clear to a bad index (1 billion should be safe)
13106         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
13107         rc=$?
13108
13109         if [ $rc -eq 0 ]; then
13110                 error "Successfully cleared to invalid CL index"
13111         elif [ $rc -ne 22 ]; then
13112                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
13113         fi
13114 }
13115 run_test 160e "changelog negative testing (should return errors)"
13116
13117 test_160f() {
13118         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13119         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13120                 skip "Need MDS version at least 2.10.56"
13121
13122         local mdts=$(comma_list $(mdts_nodes))
13123
13124         # Create a user
13125         changelog_register || error "first changelog_register failed"
13126         changelog_register || error "second changelog_register failed"
13127         local cl_users
13128         declare -A cl_user1
13129         declare -A cl_user2
13130         local user_rec1
13131         local user_rec2
13132         local i
13133
13134         # generate some changelog records to accumulate on each MDT
13135         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13136         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13137                 error "create $DIR/$tdir/$tfile failed"
13138
13139         # check changelogs have been generated
13140         local nbcl=$(changelog_dump | wc -l)
13141         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13142
13143         for param in "changelog_max_idle_time=10" \
13144                      "changelog_gc=1" \
13145                      "changelog_min_gc_interval=2" \
13146                      "changelog_min_free_cat_entries=3"; do
13147                 local MDT0=$(facet_svc $SINGLEMDS)
13148                 local var="${param%=*}"
13149                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13150
13151                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13152                 do_nodes $mdts $LCTL set_param mdd.*.$param
13153         done
13154
13155         # force cl_user2 to be idle (1st part)
13156         sleep 9
13157
13158         # simulate changelog catalog almost full
13159         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13160         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13161
13162         for i in $(seq $MDSCOUNT); do
13163                 cl_users=(${CL_USERS[mds$i]})
13164                 cl_user1[mds$i]="${cl_users[0]}"
13165                 cl_user2[mds$i]="${cl_users[1]}"
13166
13167                 [ -n "${cl_user1[mds$i]}" ] ||
13168                         error "mds$i: no user registered"
13169                 [ -n "${cl_user2[mds$i]}" ] ||
13170                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13171
13172                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13173                 [ -n "$user_rec1" ] ||
13174                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13175                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13176                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13177                 [ -n "$user_rec2" ] ||
13178                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13179                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13180                      "$user_rec1 + 2 == $user_rec2"
13181                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13182                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13183                               "$user_rec1 + 2, but is $user_rec2"
13184                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13185                 [ -n "$user_rec2" ] ||
13186                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13187                 [ $user_rec1 == $user_rec2 ] ||
13188                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13189                               "$user_rec1, but is $user_rec2"
13190         done
13191
13192         # force cl_user2 to be idle (2nd part) and to reach
13193         # changelog_max_idle_time
13194         sleep 2
13195
13196         # generate one more changelog to trigger fail_loc
13197         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13198                 error "create $DIR/$tdir/${tfile}bis failed"
13199
13200         # ensure gc thread is done
13201         for i in $(mdts_nodes); do
13202                 wait_update $i \
13203                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13204                         error "$i: GC-thread not done"
13205         done
13206
13207         local first_rec
13208         for i in $(seq $MDSCOUNT); do
13209                 # check cl_user1 still registered
13210                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13211                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13212                 # check cl_user2 unregistered
13213                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13214                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13215
13216                 # check changelogs are present and starting at $user_rec1 + 1
13217                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13218                 [ -n "$user_rec1" ] ||
13219                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13220                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13221                             awk '{ print $1; exit; }')
13222
13223                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13224                 [ $((user_rec1 + 1)) == $first_rec ] ||
13225                         error "mds$i: first index should be $user_rec1 + 1, " \
13226                               "but is $first_rec"
13227         done
13228 }
13229 run_test 160f "changelog garbage collect (timestamped users)"
13230
13231 test_160g() {
13232         remote_mds_nodsh && skip "remote MDS with nodsh"
13233         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13234                 skip "Need MDS version at least 2.10.56"
13235
13236         local mdts=$(comma_list $(mdts_nodes))
13237
13238         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
13239         do_nodes $mdts $LCTL set_param fail_loc=0x1314
13240
13241         # Create a user
13242         changelog_register || error "first changelog_register failed"
13243         changelog_register || error "second changelog_register failed"
13244         local cl_users
13245         declare -A cl_user1
13246         declare -A cl_user2
13247         local user_rec1
13248         local user_rec2
13249         local i
13250
13251         # generate some changelog records to accumulate on each MDT
13252         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13253         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13254                 error "create $DIR/$tdir/$tfile failed"
13255
13256         # check changelogs have been generated
13257         local nbcl=$(changelog_dump | wc -l)
13258         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13259
13260         # reduce the max_idle_indexes value to make sure we exceed it
13261         max_ndx=$((nbcl / 2 - 1))
13262
13263         for param in "changelog_max_idle_indexes=$max_ndx" \
13264                      "changelog_gc=1" \
13265                      "changelog_min_gc_interval=2" \
13266                      "changelog_min_free_cat_entries=3"; do
13267                 local MDT0=$(facet_svc $SINGLEMDS)
13268                 local var="${param%=*}"
13269                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13270
13271                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13272                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
13273                         error "unable to set mdd.*.$param"
13274         done
13275
13276         # simulate changelog catalog almost full
13277         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13278         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13279
13280         for i in $(seq $MDSCOUNT); do
13281                 cl_users=(${CL_USERS[mds$i]})
13282                 cl_user1[mds$i]="${cl_users[0]}"
13283                 cl_user2[mds$i]="${cl_users[1]}"
13284
13285                 [ -n "${cl_user1[mds$i]}" ] ||
13286                         error "mds$i: no user registered"
13287                 [ -n "${cl_user2[mds$i]}" ] ||
13288                         error "mds$i: only ${cl_user1[mds$i]} is registered"
13289
13290                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13291                 [ -n "$user_rec1" ] ||
13292                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13293                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13294                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13295                 [ -n "$user_rec2" ] ||
13296                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13297                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13298                      "$user_rec1 + 2 == $user_rec2"
13299                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13300                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13301                               "$user_rec1 + 2, but is $user_rec2"
13302                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13303                 [ -n "$user_rec2" ] ||
13304                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13305                 [ $user_rec1 == $user_rec2 ] ||
13306                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13307                               "$user_rec1, but is $user_rec2"
13308         done
13309
13310         # ensure we are past the previous changelog_min_gc_interval set above
13311         sleep 2
13312
13313         # generate one more changelog to trigger fail_loc
13314         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13315                 error "create $DIR/$tdir/${tfile}bis failed"
13316
13317         # ensure gc thread is done
13318         for i in $(mdts_nodes); do
13319                 wait_update $i \
13320                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13321                         error "$i: GC-thread not done"
13322         done
13323
13324         local first_rec
13325         for i in $(seq $MDSCOUNT); do
13326                 # check cl_user1 still registered
13327                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13328                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13329                 # check cl_user2 unregistered
13330                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13331                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13332
13333                 # check changelogs are present and starting at $user_rec1 + 1
13334                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13335                 [ -n "$user_rec1" ] ||
13336                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13337                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13338                             awk '{ print $1; exit; }')
13339
13340                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13341                 [ $((user_rec1 + 1)) == $first_rec ] ||
13342                         error "mds$i: first index should be $user_rec1 + 1, " \
13343                               "but is $first_rec"
13344         done
13345 }
13346 run_test 160g "changelog garbage collect (old users)"
13347
13348 test_160h() {
13349         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13350         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13351                 skip "Need MDS version at least 2.10.56"
13352
13353         local mdts=$(comma_list $(mdts_nodes))
13354
13355         # Create a user
13356         changelog_register || error "first changelog_register failed"
13357         changelog_register || error "second changelog_register failed"
13358         local cl_users
13359         declare -A cl_user1
13360         declare -A cl_user2
13361         local user_rec1
13362         local user_rec2
13363         local i
13364
13365         # generate some changelog records to accumulate on each MDT
13366         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13367         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13368                 error "create $DIR/$tdir/$tfile failed"
13369
13370         # check changelogs have been generated
13371         local nbcl=$(changelog_dump | wc -l)
13372         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13373
13374         for param in "changelog_max_idle_time=10" \
13375                      "changelog_gc=1" \
13376                      "changelog_min_gc_interval=2"; do
13377                 local MDT0=$(facet_svc $SINGLEMDS)
13378                 local var="${param%=*}"
13379                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13380
13381                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13382                 do_nodes $mdts $LCTL set_param mdd.*.$param
13383         done
13384
13385         # force cl_user2 to be idle (1st part)
13386         sleep 9
13387
13388         for i in $(seq $MDSCOUNT); do
13389                 cl_users=(${CL_USERS[mds$i]})
13390                 cl_user1[mds$i]="${cl_users[0]}"
13391                 cl_user2[mds$i]="${cl_users[1]}"
13392
13393                 [ -n "${cl_user1[mds$i]}" ] ||
13394                         error "mds$i: no user registered"
13395                 [ -n "${cl_user2[mds$i]}" ] ||
13396                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13397
13398                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13399                 [ -n "$user_rec1" ] ||
13400                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13401                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13402                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13403                 [ -n "$user_rec2" ] ||
13404                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13405                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13406                      "$user_rec1 + 2 == $user_rec2"
13407                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13408                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13409                               "$user_rec1 + 2, but is $user_rec2"
13410                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13411                 [ -n "$user_rec2" ] ||
13412                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13413                 [ $user_rec1 == $user_rec2 ] ||
13414                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13415                               "$user_rec1, but is $user_rec2"
13416         done
13417
13418         # force cl_user2 to be idle (2nd part) and to reach
13419         # changelog_max_idle_time
13420         sleep 2
13421
13422         # force each GC-thread start and block then
13423         # one per MDT/MDD, set fail_val accordingly
13424         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
13425         do_nodes $mdts $LCTL set_param fail_loc=0x1316
13426
13427         # generate more changelogs to trigger fail_loc
13428         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13429                 error "create $DIR/$tdir/${tfile}bis failed"
13430
13431         # stop MDT to stop GC-thread, should be done in back-ground as it will
13432         # block waiting for the thread to be released and exit
13433         declare -A stop_pids
13434         for i in $(seq $MDSCOUNT); do
13435                 stop mds$i &
13436                 stop_pids[mds$i]=$!
13437         done
13438
13439         for i in $(mdts_nodes); do
13440                 local facet
13441                 local nb=0
13442                 local facets=$(facets_up_on_host $i)
13443
13444                 for facet in ${facets//,/ }; do
13445                         if [[ $facet == mds* ]]; then
13446                                 nb=$((nb + 1))
13447                         fi
13448                 done
13449                 # ensure each MDS's gc threads are still present and all in "R"
13450                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
13451                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
13452                         error "$i: expected $nb GC-thread"
13453                 wait_update $i \
13454                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
13455                         "R" 20 ||
13456                         error "$i: GC-thread not found in R-state"
13457                 # check umounts of each MDT on MDS have reached kthread_stop()
13458                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
13459                         error "$i: expected $nb umount"
13460                 wait_update $i \
13461                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
13462                         error "$i: umount not found in D-state"
13463         done
13464
13465         # release all GC-threads
13466         do_nodes $mdts $LCTL set_param fail_loc=0
13467
13468         # wait for MDT stop to complete
13469         for i in $(seq $MDSCOUNT); do
13470                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
13471         done
13472
13473         # XXX
13474         # may try to check if any orphan changelog records are present
13475         # via ldiskfs/zfs and llog_reader...
13476
13477         # re-start/mount MDTs
13478         for i in $(seq $MDSCOUNT); do
13479                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
13480                         error "Fail to start mds$i"
13481         done
13482
13483         local first_rec
13484         for i in $(seq $MDSCOUNT); do
13485                 # check cl_user1 still registered
13486                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13487                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13488                 # check cl_user2 unregistered
13489                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13490                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13491
13492                 # check changelogs are present and starting at $user_rec1 + 1
13493                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13494                 [ -n "$user_rec1" ] ||
13495                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13496                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13497                             awk '{ print $1; exit; }')
13498
13499                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13500                 [ $((user_rec1 + 1)) == $first_rec ] ||
13501                         error "mds$i: first index should be $user_rec1 + 1, " \
13502                               "but is $first_rec"
13503         done
13504 }
13505 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
13506               "during mount"
13507
13508 test_160i() {
13509
13510         local mdts=$(comma_list $(mdts_nodes))
13511
13512         changelog_register || error "first changelog_register failed"
13513
13514         # generate some changelog records to accumulate on each MDT
13515         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13516         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13517                 error "create $DIR/$tdir/$tfile failed"
13518
13519         # check changelogs have been generated
13520         local nbcl=$(changelog_dump | wc -l)
13521         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13522
13523         # simulate race between register and unregister
13524         # XXX as fail_loc is set per-MDS, with DNE configs the race
13525         # simulation will only occur for one MDT per MDS and for the
13526         # others the normal race scenario will take place
13527         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
13528         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
13529         do_nodes $mdts $LCTL set_param fail_val=1
13530
13531         # unregister 1st user
13532         changelog_deregister &
13533         local pid1=$!
13534         # wait some time for deregister work to reach race rdv
13535         sleep 2
13536         # register 2nd user
13537         changelog_register || error "2nd user register failed"
13538
13539         wait $pid1 || error "1st user deregister failed"
13540
13541         local i
13542         local last_rec
13543         declare -A LAST_REC
13544         for i in $(seq $MDSCOUNT); do
13545                 if changelog_users mds$i | grep "^cl"; then
13546                         # make sure new records are added with one user present
13547                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
13548                                           awk '/^current.index:/ { print $NF }')
13549                 else
13550                         error "mds$i has no user registered"
13551                 fi
13552         done
13553
13554         # generate more changelog records to accumulate on each MDT
13555         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13556                 error "create $DIR/$tdir/${tfile}bis failed"
13557
13558         for i in $(seq $MDSCOUNT); do
13559                 last_rec=$(changelog_users $SINGLEMDS |
13560                            awk '/^current.index:/ { print $NF }')
13561                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
13562                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
13563                         error "changelogs are off on mds$i"
13564         done
13565 }
13566 run_test 160i "changelog user register/unregister race"
13567
13568 test_161a() {
13569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13570
13571         test_mkdir -c1 $DIR/$tdir
13572         cp /etc/hosts $DIR/$tdir/$tfile
13573         test_mkdir -c1 $DIR/$tdir/foo1
13574         test_mkdir -c1 $DIR/$tdir/foo2
13575         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
13576         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
13577         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
13578         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
13579         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
13580         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13581                 $LFS fid2path $DIR $FID
13582                 error "bad link ea"
13583         fi
13584         # middle
13585         rm $DIR/$tdir/foo2/zachary
13586         # last
13587         rm $DIR/$tdir/foo2/thor
13588         # first
13589         rm $DIR/$tdir/$tfile
13590         # rename
13591         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
13592         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
13593                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
13594         rm $DIR/$tdir/foo2/maggie
13595
13596         # overflow the EA
13597         local longname=$tfile.avg_len_is_thirty_two_
13598         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
13599                 error_noexit 'failed to unlink many hardlinks'" EXIT
13600         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
13601                 error "failed to hardlink many files"
13602         links=$($LFS fid2path $DIR $FID | wc -l)
13603         echo -n "${links}/1000 links in link EA"
13604         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
13605 }
13606 run_test 161a "link ea sanity"
13607
13608 test_161b() {
13609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13610         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
13611
13612         local MDTIDX=1
13613         local remote_dir=$DIR/$tdir/remote_dir
13614
13615         mkdir -p $DIR/$tdir
13616         $LFS mkdir -i $MDTIDX $remote_dir ||
13617                 error "create remote directory failed"
13618
13619         cp /etc/hosts $remote_dir/$tfile
13620         mkdir -p $remote_dir/foo1
13621         mkdir -p $remote_dir/foo2
13622         ln $remote_dir/$tfile $remote_dir/foo1/sofia
13623         ln $remote_dir/$tfile $remote_dir/foo2/zachary
13624         ln $remote_dir/$tfile $remote_dir/foo1/luna
13625         ln $remote_dir/$tfile $remote_dir/foo2/thor
13626
13627         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
13628                      tr -d ']')
13629         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13630                 $LFS fid2path $DIR $FID
13631                 error "bad link ea"
13632         fi
13633         # middle
13634         rm $remote_dir/foo2/zachary
13635         # last
13636         rm $remote_dir/foo2/thor
13637         # first
13638         rm $remote_dir/$tfile
13639         # rename
13640         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
13641         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
13642         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
13643                 $LFS fid2path $DIR $FID
13644                 error "bad link rename"
13645         fi
13646         rm $remote_dir/foo2/maggie
13647
13648         # overflow the EA
13649         local longname=filename_avg_len_is_thirty_two_
13650         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
13651                 error "failed to hardlink many files"
13652         links=$($LFS fid2path $DIR $FID | wc -l)
13653         echo -n "${links}/1000 links in link EA"
13654         [[ ${links} -gt 60 ]] ||
13655                 error "expected at least 60 links in link EA"
13656         unlinkmany $remote_dir/foo2/$longname 1000 ||
13657         error "failed to unlink many hardlinks"
13658 }
13659 run_test 161b "link ea sanity under remote directory"
13660
13661 test_161c() {
13662         remote_mds_nodsh && skip "remote MDS with nodsh"
13663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13664         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
13665                 skip "Need MDS version at least 2.1.5"
13666
13667         # define CLF_RENAME_LAST 0x0001
13668         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
13669         changelog_register || error "changelog_register failed"
13670
13671         rm -rf $DIR/$tdir
13672         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
13673         touch $DIR/$tdir/foo_161c
13674         touch $DIR/$tdir/bar_161c
13675         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13676         changelog_dump | grep RENME | tail -n 5
13677         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13678         changelog_clear 0 || error "changelog_clear failed"
13679         if [ x$flags != "x0x1" ]; then
13680                 error "flag $flags is not 0x1"
13681         fi
13682
13683         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
13684         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
13685         touch $DIR/$tdir/foo_161c
13686         touch $DIR/$tdir/bar_161c
13687         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13688         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13689         changelog_dump | grep RENME | tail -n 5
13690         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13691         changelog_clear 0 || error "changelog_clear failed"
13692         if [ x$flags != "x0x0" ]; then
13693                 error "flag $flags is not 0x0"
13694         fi
13695         echo "rename overwrite a target having nlink > 1," \
13696                 "changelog record has flags of $flags"
13697
13698         # rename doesn't overwrite a target (changelog flag 0x0)
13699         touch $DIR/$tdir/foo_161c
13700         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
13701         changelog_dump | grep RENME | tail -n 5
13702         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
13703         changelog_clear 0 || error "changelog_clear failed"
13704         if [ x$flags != "x0x0" ]; then
13705                 error "flag $flags is not 0x0"
13706         fi
13707         echo "rename doesn't overwrite a target," \
13708                 "changelog record has flags of $flags"
13709
13710         # define CLF_UNLINK_LAST 0x0001
13711         # unlink a file having nlink = 1 (changelog flag 0x1)
13712         rm -f $DIR/$tdir/foo2_161c
13713         changelog_dump | grep UNLNK | tail -n 5
13714         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13715         changelog_clear 0 || error "changelog_clear failed"
13716         if [ x$flags != "x0x1" ]; then
13717                 error "flag $flags is not 0x1"
13718         fi
13719         echo "unlink a file having nlink = 1," \
13720                 "changelog record has flags of $flags"
13721
13722         # unlink a file having nlink > 1 (changelog flag 0x0)
13723         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13724         rm -f $DIR/$tdir/foobar_161c
13725         changelog_dump | grep UNLNK | tail -n 5
13726         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13727         changelog_clear 0 || error "changelog_clear failed"
13728         if [ x$flags != "x0x0" ]; then
13729                 error "flag $flags is not 0x0"
13730         fi
13731         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
13732 }
13733 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
13734
13735 test_161d() {
13736         remote_mds_nodsh && skip "remote MDS with nodsh"
13737         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
13738
13739         local pid
13740         local fid
13741
13742         changelog_register || error "changelog_register failed"
13743
13744         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
13745         # interfer with $MOUNT/.lustre/fid/ access
13746         mkdir $DIR/$tdir
13747         [[ $? -eq 0 ]] || error "mkdir failed"
13748
13749         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
13750         $LCTL set_param fail_loc=0x8000140c
13751         # 5s pause
13752         $LCTL set_param fail_val=5
13753
13754         # create file
13755         echo foofoo > $DIR/$tdir/$tfile &
13756         pid=$!
13757
13758         # wait for create to be delayed
13759         sleep 2
13760
13761         ps -p $pid
13762         [[ $? -eq 0 ]] || error "create should be blocked"
13763
13764         local tempfile=$(mktemp)
13765         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
13766         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
13767         # some delay may occur during ChangeLog publishing and file read just
13768         # above, that could allow file write to happen finally
13769         [[ -s $tempfile ]] && echo "file should be empty"
13770
13771         $LCTL set_param fail_loc=0
13772
13773         wait $pid
13774         [[ $? -eq 0 ]] || error "create failed"
13775 }
13776 run_test 161d "create with concurrent .lustre/fid access"
13777
13778 check_path() {
13779         local expected="$1"
13780         shift
13781         local fid="$2"
13782
13783         local path
13784         path=$($LFS fid2path "$@")
13785         local rc=$?
13786
13787         if [ $rc -ne 0 ]; then
13788                 error "path looked up of '$expected' failed: rc=$rc"
13789         elif [ "$path" != "$expected" ]; then
13790                 error "path looked up '$path' instead of '$expected'"
13791         else
13792                 echo "FID '$fid' resolves to path '$path' as expected"
13793         fi
13794 }
13795
13796 test_162a() { # was test_162
13797         test_mkdir -p -c1 $DIR/$tdir/d2
13798         touch $DIR/$tdir/d2/$tfile
13799         touch $DIR/$tdir/d2/x1
13800         touch $DIR/$tdir/d2/x2
13801         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
13802         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
13803         # regular file
13804         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
13805         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
13806
13807         # softlink
13808         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
13809         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
13810         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
13811
13812         # softlink to wrong file
13813         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
13814         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
13815         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
13816
13817         # hardlink
13818         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
13819         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
13820         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
13821         # fid2path dir/fsname should both work
13822         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
13823         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
13824
13825         # hardlink count: check that there are 2 links
13826         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
13827         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
13828
13829         # hardlink indexing: remove the first link
13830         rm $DIR/$tdir/d2/p/q/r/hlink
13831         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
13832 }
13833 run_test 162a "path lookup sanity"
13834
13835 test_162b() {
13836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13837         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13838
13839         mkdir $DIR/$tdir
13840         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
13841                                 error "create striped dir failed"
13842
13843         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
13844                                         tail -n 1 | awk '{print $2}')
13845         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
13846
13847         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
13848         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
13849
13850         # regular file
13851         for ((i=0;i<5;i++)); do
13852                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
13853                         error "get fid for f$i failed"
13854                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
13855
13856                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
13857                         error "get fid for d$i failed"
13858                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
13859         done
13860
13861         return 0
13862 }
13863 run_test 162b "striped directory path lookup sanity"
13864
13865 # LU-4239: Verify fid2path works with paths 100 or more directories deep
13866 test_162c() {
13867         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
13868                 skip "Need MDS version at least 2.7.51"
13869
13870         local lpath=$tdir.local
13871         local rpath=$tdir.remote
13872
13873         test_mkdir $DIR/$lpath
13874         test_mkdir $DIR/$rpath
13875
13876         for ((i = 0; i <= 101; i++)); do
13877                 lpath="$lpath/$i"
13878                 mkdir $DIR/$lpath
13879                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
13880                         error "get fid for local directory $DIR/$lpath failed"
13881                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
13882
13883                 rpath="$rpath/$i"
13884                 test_mkdir $DIR/$rpath
13885                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
13886                         error "get fid for remote directory $DIR/$rpath failed"
13887                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
13888         done
13889
13890         return 0
13891 }
13892 run_test 162c "fid2path works with paths 100 or more directories deep"
13893
13894 test_169() {
13895         # do directio so as not to populate the page cache
13896         log "creating a 10 Mb file"
13897         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
13898         log "starting reads"
13899         dd if=$DIR/$tfile of=/dev/null bs=4096 &
13900         log "truncating the file"
13901         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
13902         log "killing dd"
13903         kill %+ || true # reads might have finished
13904         echo "wait until dd is finished"
13905         wait
13906         log "removing the temporary file"
13907         rm -rf $DIR/$tfile || error "tmp file removal failed"
13908 }
13909 run_test 169 "parallel read and truncate should not deadlock"
13910
13911 test_170() {
13912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13913
13914         $LCTL clear     # bug 18514
13915         $LCTL debug_daemon start $TMP/${tfile}_log_good
13916         touch $DIR/$tfile
13917         $LCTL debug_daemon stop
13918         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
13919                 error "sed failed to read log_good"
13920
13921         $LCTL debug_daemon start $TMP/${tfile}_log_good
13922         rm -rf $DIR/$tfile
13923         $LCTL debug_daemon stop
13924
13925         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
13926                error "lctl df log_bad failed"
13927
13928         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13929         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13930
13931         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
13932         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
13933
13934         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
13935                 error "bad_line good_line1 good_line2 are empty"
13936
13937         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13938         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
13939         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13940
13941         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
13942         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13943         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13944
13945         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
13946                 error "bad_line_new good_line_new are empty"
13947
13948         local expected_good=$((good_line1 + good_line2*2))
13949
13950         rm -f $TMP/${tfile}*
13951         # LU-231, short malformed line may not be counted into bad lines
13952         if [ $bad_line -ne $bad_line_new ] &&
13953                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
13954                 error "expected $bad_line bad lines, but got $bad_line_new"
13955                 return 1
13956         fi
13957
13958         if [ $expected_good -ne $good_line_new ]; then
13959                 error "expected $expected_good good lines, but got $good_line_new"
13960                 return 2
13961         fi
13962         true
13963 }
13964 run_test 170 "test lctl df to handle corrupted log ====================="
13965
13966 test_171() { # bug20592
13967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13968
13969         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
13970         $LCTL set_param fail_loc=0x50e
13971         $LCTL set_param fail_val=3000
13972         multiop_bg_pause $DIR/$tfile O_s || true
13973         local MULTIPID=$!
13974         kill -USR1 $MULTIPID
13975         # cause log dump
13976         sleep 3
13977         wait $MULTIPID
13978         if dmesg | grep "recursive fault"; then
13979                 error "caught a recursive fault"
13980         fi
13981         $LCTL set_param fail_loc=0
13982         true
13983 }
13984 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
13985
13986 # it would be good to share it with obdfilter-survey/iokit-libecho code
13987 setup_obdecho_osc () {
13988         local rc=0
13989         local ost_nid=$1
13990         local obdfilter_name=$2
13991         echo "Creating new osc for $obdfilter_name on $ost_nid"
13992         # make sure we can find loopback nid
13993         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
13994
13995         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
13996                            ${obdfilter_name}_osc_UUID || rc=2; }
13997         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
13998                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
13999         return $rc
14000 }
14001
14002 cleanup_obdecho_osc () {
14003         local obdfilter_name=$1
14004         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
14005         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
14006         return 0
14007 }
14008
14009 obdecho_test() {
14010         local OBD=$1
14011         local node=$2
14012         local pages=${3:-64}
14013         local rc=0
14014         local id
14015
14016         local count=10
14017         local obd_size=$(get_obd_size $node $OBD)
14018         local page_size=$(get_page_size $node)
14019         if [[ -n "$obd_size" ]]; then
14020                 local new_count=$((obd_size / (pages * page_size / 1024)))
14021                 [[ $new_count -ge $count ]] || count=$new_count
14022         fi
14023
14024         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
14025         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
14026                            rc=2; }
14027         if [ $rc -eq 0 ]; then
14028             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
14029             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
14030         fi
14031         echo "New object id is $id"
14032         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
14033                            rc=4; }
14034         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
14035                            "test_brw $count w v $pages $id" || rc=4; }
14036         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
14037                            rc=4; }
14038         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
14039                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
14040         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
14041                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
14042         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
14043         return $rc
14044 }
14045
14046 test_180a() {
14047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14048
14049         if ! module_loaded obdecho; then
14050                 load_module obdecho/obdecho &&
14051                         stack_trap "rmmod obdecho" EXIT ||
14052                         error "unable to load obdecho on client"
14053         fi
14054
14055         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
14056         local host=$($LCTL get_param -n osc.$osc.import |
14057                      awk '/current_connection:/ { print $2 }' )
14058         local target=$($LCTL get_param -n osc.$osc.import |
14059                        awk '/target:/ { print $2 }' )
14060         target=${target%_UUID}
14061
14062         if [ -n "$target" ]; then
14063                 setup_obdecho_osc $host $target &&
14064                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
14065                         { error "obdecho setup failed with $?"; return; }
14066
14067                 obdecho_test ${target}_osc client ||
14068                         error "obdecho_test failed on ${target}_osc"
14069         else
14070                 $LCTL get_param osc.$osc.import
14071                 error "there is no osc.$osc.import target"
14072         fi
14073 }
14074 run_test 180a "test obdecho on osc"
14075
14076 test_180b() {
14077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14078         remote_ost_nodsh && skip "remote OST with nodsh"
14079
14080         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14081                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14082                 error "failed to load module obdecho"
14083
14084         local target=$(do_facet ost1 $LCTL dl |
14085                        awk '/obdfilter/ { print $4; exit; }')
14086
14087         if [ -n "$target" ]; then
14088                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
14089         else
14090                 do_facet ost1 $LCTL dl
14091                 error "there is no obdfilter target on ost1"
14092         fi
14093 }
14094 run_test 180b "test obdecho directly on obdfilter"
14095
14096 test_180c() { # LU-2598
14097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14098         remote_ost_nodsh && skip "remote OST with nodsh"
14099         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
14100                 skip "Need MDS version at least 2.4.0"
14101
14102         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14103                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14104                 error "failed to load module obdecho"
14105
14106         local target=$(do_facet ost1 $LCTL dl |
14107                        awk '/obdfilter/ { print $4; exit; }')
14108
14109         if [ -n "$target" ]; then
14110                 local pages=16384 # 64MB bulk I/O RPC size
14111
14112                 obdecho_test "$target" ost1 "$pages" ||
14113                         error "obdecho_test with pages=$pages failed with $?"
14114         else
14115                 do_facet ost1 $LCTL dl
14116                 error "there is no obdfilter target on ost1"
14117         fi
14118 }
14119 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
14120
14121 test_181() { # bug 22177
14122         test_mkdir $DIR/$tdir
14123         # create enough files to index the directory
14124         createmany -o $DIR/$tdir/foobar 4000
14125         # print attributes for debug purpose
14126         lsattr -d .
14127         # open dir
14128         multiop_bg_pause $DIR/$tdir D_Sc || return 1
14129         MULTIPID=$!
14130         # remove the files & current working dir
14131         unlinkmany $DIR/$tdir/foobar 4000
14132         rmdir $DIR/$tdir
14133         kill -USR1 $MULTIPID
14134         wait $MULTIPID
14135         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
14136         return 0
14137 }
14138 run_test 181 "Test open-unlinked dir ========================"
14139
14140 test_182() {
14141         local fcount=1000
14142         local tcount=10
14143
14144         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14145
14146         $LCTL set_param mdc.*.rpc_stats=clear
14147
14148         for (( i = 0; i < $tcount; i++ )) ; do
14149                 mkdir $DIR/$tdir/$i
14150         done
14151
14152         for (( i = 0; i < $tcount; i++ )) ; do
14153                 createmany -o $DIR/$tdir/$i/f- $fcount &
14154         done
14155         wait
14156
14157         for (( i = 0; i < $tcount; i++ )) ; do
14158                 unlinkmany $DIR/$tdir/$i/f- $fcount &
14159         done
14160         wait
14161
14162         $LCTL get_param mdc.*.rpc_stats
14163
14164         rm -rf $DIR/$tdir
14165 }
14166 run_test 182 "Test parallel modify metadata operations ================"
14167
14168 test_183() { # LU-2275
14169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14170         remote_mds_nodsh && skip "remote MDS with nodsh"
14171         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
14172                 skip "Need MDS version at least 2.3.56"
14173
14174         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14175         echo aaa > $DIR/$tdir/$tfile
14176
14177 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
14178         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
14179
14180         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
14181         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
14182
14183         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
14184
14185         # Flush negative dentry cache
14186         touch $DIR/$tdir/$tfile
14187
14188         # We are not checking for any leaked references here, they'll
14189         # become evident next time we do cleanup with module unload.
14190         rm -rf $DIR/$tdir
14191 }
14192 run_test 183 "No crash or request leak in case of strange dispositions ========"
14193
14194 # test suite 184 is for LU-2016, LU-2017
14195 test_184a() {
14196         check_swap_layouts_support
14197
14198         dir0=$DIR/$tdir/$testnum
14199         test_mkdir -p -c1 $dir0
14200         ref1=/etc/passwd
14201         ref2=/etc/group
14202         file1=$dir0/f1
14203         file2=$dir0/f2
14204         $LFS setstripe -c1 $file1
14205         cp $ref1 $file1
14206         $LFS setstripe -c2 $file2
14207         cp $ref2 $file2
14208         gen1=$($LFS getstripe -g $file1)
14209         gen2=$($LFS getstripe -g $file2)
14210
14211         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
14212         gen=$($LFS getstripe -g $file1)
14213         [[ $gen1 != $gen ]] ||
14214                 "Layout generation on $file1 does not change"
14215         gen=$($LFS getstripe -g $file2)
14216         [[ $gen2 != $gen ]] ||
14217                 "Layout generation on $file2 does not change"
14218
14219         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
14220         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
14221
14222         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
14223 }
14224 run_test 184a "Basic layout swap"
14225
14226 test_184b() {
14227         check_swap_layouts_support
14228
14229         dir0=$DIR/$tdir/$testnum
14230         mkdir -p $dir0 || error "creating dir $dir0"
14231         file1=$dir0/f1
14232         file2=$dir0/f2
14233         file3=$dir0/f3
14234         dir1=$dir0/d1
14235         dir2=$dir0/d2
14236         mkdir $dir1 $dir2
14237         $LFS setstripe -c1 $file1
14238         $LFS setstripe -c2 $file2
14239         $LFS setstripe -c1 $file3
14240         chown $RUNAS_ID $file3
14241         gen1=$($LFS getstripe -g $file1)
14242         gen2=$($LFS getstripe -g $file2)
14243
14244         $LFS swap_layouts $dir1 $dir2 &&
14245                 error "swap of directories layouts should fail"
14246         $LFS swap_layouts $dir1 $file1 &&
14247                 error "swap of directory and file layouts should fail"
14248         $RUNAS $LFS swap_layouts $file1 $file2 &&
14249                 error "swap of file we cannot write should fail"
14250         $LFS swap_layouts $file1 $file3 &&
14251                 error "swap of file with different owner should fail"
14252         /bin/true # to clear error code
14253 }
14254 run_test 184b "Forbidden layout swap (will generate errors)"
14255
14256 test_184c() {
14257         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
14258         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
14259         check_swap_layouts_support
14260
14261         local dir0=$DIR/$tdir/$testnum
14262         mkdir -p $dir0 || error "creating dir $dir0"
14263
14264         local ref1=$dir0/ref1
14265         local ref2=$dir0/ref2
14266         local file1=$dir0/file1
14267         local file2=$dir0/file2
14268         # create a file large enough for the concurrent test
14269         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
14270         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
14271         echo "ref file size: ref1($(stat -c %s $ref1))," \
14272              "ref2($(stat -c %s $ref2))"
14273
14274         cp $ref2 $file2
14275         dd if=$ref1 of=$file1 bs=16k &
14276         local DD_PID=$!
14277
14278         # Make sure dd starts to copy file
14279         while [ ! -f $file1 ]; do sleep 0.1; done
14280
14281         $LFS swap_layouts $file1 $file2
14282         local rc=$?
14283         wait $DD_PID
14284         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
14285         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
14286
14287         # how many bytes copied before swapping layout
14288         local copied=$(stat -c %s $file2)
14289         local remaining=$(stat -c %s $ref1)
14290         remaining=$((remaining - copied))
14291         echo "Copied $copied bytes before swapping layout..."
14292
14293         cmp -n $copied $file1 $ref2 | grep differ &&
14294                 error "Content mismatch [0, $copied) of ref2 and file1"
14295         cmp -n $copied $file2 $ref1 ||
14296                 error "Content mismatch [0, $copied) of ref1 and file2"
14297         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
14298                 error "Content mismatch [$copied, EOF) of ref1 and file1"
14299
14300         # clean up
14301         rm -f $ref1 $ref2 $file1 $file2
14302 }
14303 run_test 184c "Concurrent write and layout swap"
14304
14305 test_184d() {
14306         check_swap_layouts_support
14307         [ -z "$(which getfattr 2>/dev/null)" ] &&
14308                 skip_env "no getfattr command"
14309
14310         local file1=$DIR/$tdir/$tfile-1
14311         local file2=$DIR/$tdir/$tfile-2
14312         local file3=$DIR/$tdir/$tfile-3
14313         local lovea1
14314         local lovea2
14315
14316         mkdir -p $DIR/$tdir
14317         touch $file1 || error "create $file1 failed"
14318         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14319                 error "create $file2 failed"
14320         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14321                 error "create $file3 failed"
14322         lovea1=$(get_layout_param $file1)
14323
14324         $LFS swap_layouts $file2 $file3 ||
14325                 error "swap $file2 $file3 layouts failed"
14326         $LFS swap_layouts $file1 $file2 ||
14327                 error "swap $file1 $file2 layouts failed"
14328
14329         lovea2=$(get_layout_param $file2)
14330         echo "$lovea1"
14331         echo "$lovea2"
14332         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
14333
14334         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14335         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
14336 }
14337 run_test 184d "allow stripeless layouts swap"
14338
14339 test_184e() {
14340         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
14341                 skip "Need MDS version at least 2.6.94"
14342         check_swap_layouts_support
14343         [ -z "$(which getfattr 2>/dev/null)" ] &&
14344                 skip_env "no getfattr command"
14345
14346         local file1=$DIR/$tdir/$tfile-1
14347         local file2=$DIR/$tdir/$tfile-2
14348         local file3=$DIR/$tdir/$tfile-3
14349         local lovea
14350
14351         mkdir -p $DIR/$tdir
14352         touch $file1 || error "create $file1 failed"
14353         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14354                 error "create $file2 failed"
14355         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14356                 error "create $file3 failed"
14357
14358         $LFS swap_layouts $file1 $file2 ||
14359                 error "swap $file1 $file2 layouts failed"
14360
14361         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14362         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
14363
14364         echo 123 > $file1 || error "Should be able to write into $file1"
14365
14366         $LFS swap_layouts $file1 $file3 ||
14367                 error "swap $file1 $file3 layouts failed"
14368
14369         echo 123 > $file1 || error "Should be able to write into $file1"
14370
14371         rm -rf $file1 $file2 $file3
14372 }
14373 run_test 184e "Recreate layout after stripeless layout swaps"
14374
14375 test_184f() {
14376         # Create a file with name longer than sizeof(struct stat) ==
14377         # 144 to see if we can get chars from the file name to appear
14378         # in the returned striping. Note that 'f' == 0x66.
14379         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
14380
14381         mkdir -p $DIR/$tdir
14382         mcreate $DIR/$tdir/$file
14383         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
14384                 error "IOC_MDC_GETFILEINFO returned garbage striping"
14385         fi
14386 }
14387 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
14388
14389 test_185() { # LU-2441
14390         # LU-3553 - no volatile file support in old servers
14391         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
14392                 skip "Need MDS version at least 2.3.60"
14393
14394         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14395         touch $DIR/$tdir/spoo
14396         local mtime1=$(stat -c "%Y" $DIR/$tdir)
14397         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
14398                 error "cannot create/write a volatile file"
14399         [ "$FILESET" == "" ] &&
14400         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
14401                 error "FID is still valid after close"
14402
14403         multiop_bg_pause $DIR/$tdir vVw4096_c
14404         local multi_pid=$!
14405
14406         local OLD_IFS=$IFS
14407         IFS=":"
14408         local fidv=($fid)
14409         IFS=$OLD_IFS
14410         # assume that the next FID for this client is sequential, since stdout
14411         # is unfortunately eaten by multiop_bg_pause
14412         local n=$((${fidv[1]} + 1))
14413         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
14414         if [ "$FILESET" == "" ]; then
14415                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
14416                         error "FID is missing before close"
14417         fi
14418         kill -USR1 $multi_pid
14419         # 1 second delay, so if mtime change we will see it
14420         sleep 1
14421         local mtime2=$(stat -c "%Y" $DIR/$tdir)
14422         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
14423 }
14424 run_test 185 "Volatile file support"
14425
14426 test_187a() {
14427         remote_mds_nodsh && skip "remote MDS with nodsh"
14428         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
14429                 skip "Need MDS version at least 2.3.0"
14430
14431         local dir0=$DIR/$tdir/$testnum
14432         mkdir -p $dir0 || error "creating dir $dir0"
14433
14434         local file=$dir0/file1
14435         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
14436         local dv1=$($LFS data_version $file)
14437         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
14438         local dv2=$($LFS data_version $file)
14439         [[ $dv1 != $dv2 ]] ||
14440                 error "data version did not change on write $dv1 == $dv2"
14441
14442         # clean up
14443         rm -f $file1
14444 }
14445 run_test 187a "Test data version change"
14446
14447 test_187b() {
14448         remote_mds_nodsh && skip "remote MDS with nodsh"
14449         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
14450                 skip "Need MDS version at least 2.3.0"
14451
14452         local dir0=$DIR/$tdir/$testnum
14453         mkdir -p $dir0 || error "creating dir $dir0"
14454
14455         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
14456         [[ ${DV[0]} != ${DV[1]} ]] ||
14457                 error "data version did not change on write"\
14458                       " ${DV[0]} == ${DV[1]}"
14459
14460         # clean up
14461         rm -f $file1
14462 }
14463 run_test 187b "Test data version change on volatile file"
14464
14465 test_200() {
14466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14467         remote_mgs_nodsh && skip "remote MGS with nodsh"
14468         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14469
14470         local POOL=${POOL:-cea1}
14471         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
14472         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
14473         # Pool OST targets
14474         local first_ost=0
14475         local last_ost=$(($OSTCOUNT - 1))
14476         local ost_step=2
14477         local ost_list=$(seq $first_ost $ost_step $last_ost)
14478         local ost_range="$first_ost $last_ost $ost_step"
14479         local test_path=$POOL_ROOT/$POOL_DIR_NAME
14480         local file_dir=$POOL_ROOT/file_tst
14481         local subdir=$test_path/subdir
14482         local rc=0
14483
14484         if ! combined_mgs_mds ; then
14485                 mount_mgs_client
14486         fi
14487
14488         while : ; do
14489                 # former test_200a test_200b
14490                 pool_add $POOL                          || { rc=$? ; break; }
14491                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
14492                 # former test_200c test_200d
14493                 mkdir -p $test_path
14494                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
14495                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
14496                 mkdir -p $subdir
14497                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
14498                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
14499                                                         || { rc=$? ; break; }
14500                 # former test_200e test_200f
14501                 local files=$((OSTCOUNT*3))
14502                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
14503                                                         || { rc=$? ; break; }
14504                 pool_create_files $POOL $file_dir $files "$ost_list" \
14505                                                         || { rc=$? ; break; }
14506                 # former test_200g test_200h
14507                 pool_lfs_df $POOL                       || { rc=$? ; break; }
14508                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
14509
14510                 # former test_201a test_201b test_201c
14511                 pool_remove_first_target $POOL          || { rc=$? ; break; }
14512
14513                 local f=$test_path/$tfile
14514                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
14515                 pool_remove $POOL $f                    || { rc=$? ; break; }
14516                 break
14517         done
14518
14519         destroy_test_pools
14520
14521         if ! combined_mgs_mds ; then
14522                 umount_mgs_client
14523         fi
14524         return $rc
14525 }
14526 run_test 200 "OST pools"
14527
14528 # usage: default_attr <count | size | offset>
14529 default_attr() {
14530         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
14531 }
14532
14533 # usage: check_default_stripe_attr
14534 check_default_stripe_attr() {
14535         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
14536         case $1 in
14537         --stripe-count|-c)
14538                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
14539         --stripe-size|-S)
14540                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
14541         --stripe-index|-i)
14542                 EXPECTED=-1;;
14543         *)
14544                 error "unknown getstripe attr '$1'"
14545         esac
14546
14547         [ $ACTUAL == $EXPECTED ] ||
14548                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
14549 }
14550
14551 test_204a() {
14552         test_mkdir $DIR/$tdir
14553         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
14554
14555         check_default_stripe_attr --stripe-count
14556         check_default_stripe_attr --stripe-size
14557         check_default_stripe_attr --stripe-index
14558 }
14559 run_test 204a "Print default stripe attributes"
14560
14561 test_204b() {
14562         test_mkdir $DIR/$tdir
14563         $LFS setstripe --stripe-count 1 $DIR/$tdir
14564
14565         check_default_stripe_attr --stripe-size
14566         check_default_stripe_attr --stripe-index
14567 }
14568 run_test 204b "Print default stripe size and offset"
14569
14570 test_204c() {
14571         test_mkdir $DIR/$tdir
14572         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14573
14574         check_default_stripe_attr --stripe-count
14575         check_default_stripe_attr --stripe-index
14576 }
14577 run_test 204c "Print default stripe count and offset"
14578
14579 test_204d() {
14580         test_mkdir $DIR/$tdir
14581         $LFS setstripe --stripe-index 0 $DIR/$tdir
14582
14583         check_default_stripe_attr --stripe-count
14584         check_default_stripe_attr --stripe-size
14585 }
14586 run_test 204d "Print default stripe count and size"
14587
14588 test_204e() {
14589         test_mkdir $DIR/$tdir
14590         $LFS setstripe -d $DIR/$tdir
14591
14592         check_default_stripe_attr --stripe-count --raw
14593         check_default_stripe_attr --stripe-size --raw
14594         check_default_stripe_attr --stripe-index --raw
14595 }
14596 run_test 204e "Print raw stripe attributes"
14597
14598 test_204f() {
14599         test_mkdir $DIR/$tdir
14600         $LFS setstripe --stripe-count 1 $DIR/$tdir
14601
14602         check_default_stripe_attr --stripe-size --raw
14603         check_default_stripe_attr --stripe-index --raw
14604 }
14605 run_test 204f "Print raw stripe size and offset"
14606
14607 test_204g() {
14608         test_mkdir $DIR/$tdir
14609         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14610
14611         check_default_stripe_attr --stripe-count --raw
14612         check_default_stripe_attr --stripe-index --raw
14613 }
14614 run_test 204g "Print raw stripe count and offset"
14615
14616 test_204h() {
14617         test_mkdir $DIR/$tdir
14618         $LFS setstripe --stripe-index 0 $DIR/$tdir
14619
14620         check_default_stripe_attr --stripe-count --raw
14621         check_default_stripe_attr --stripe-size --raw
14622 }
14623 run_test 204h "Print raw stripe count and size"
14624
14625 # Figure out which job scheduler is being used, if any,
14626 # or use a fake one
14627 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
14628         JOBENV=SLURM_JOB_ID
14629 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
14630         JOBENV=LSB_JOBID
14631 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
14632         JOBENV=PBS_JOBID
14633 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
14634         JOBENV=LOADL_STEP_ID
14635 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
14636         JOBENV=JOB_ID
14637 else
14638         $LCTL list_param jobid_name > /dev/null 2>&1
14639         if [ $? -eq 0 ]; then
14640                 JOBENV=nodelocal
14641         else
14642                 JOBENV=FAKE_JOBID
14643         fi
14644 fi
14645 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
14646
14647 verify_jobstats() {
14648         local cmd=($1)
14649         shift
14650         local facets="$@"
14651
14652 # we don't really need to clear the stats for this test to work, since each
14653 # command has a unique jobid, but it makes debugging easier if needed.
14654 #       for facet in $facets; do
14655 #               local dev=$(convert_facet2label $facet)
14656 #               # clear old jobstats
14657 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
14658 #       done
14659
14660         # use a new JobID for each test, or we might see an old one
14661         [ "$JOBENV" = "FAKE_JOBID" ] &&
14662                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
14663
14664         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
14665
14666         [ "$JOBENV" = "nodelocal" ] && {
14667                 FAKE_JOBID=id.$testnum.%e.$RANDOM
14668                 $LCTL set_param jobid_name=$FAKE_JOBID
14669                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
14670         }
14671
14672         log "Test: ${cmd[*]}"
14673         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
14674
14675         if [ $JOBENV = "FAKE_JOBID" ]; then
14676                 FAKE_JOBID=$JOBVAL ${cmd[*]}
14677         else
14678                 ${cmd[*]}
14679         fi
14680
14681         # all files are created on OST0000
14682         for facet in $facets; do
14683                 local stats="*.$(convert_facet2label $facet).job_stats"
14684
14685                 # strip out libtool wrappers for in-tree executables
14686                 if [ $(do_facet $facet lctl get_param $stats |
14687                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
14688                         do_facet $facet lctl get_param $stats
14689                         error "No jobstats for $JOBVAL found on $facet::$stats"
14690                 fi
14691         done
14692 }
14693
14694 jobstats_set() {
14695         local new_jobenv=$1
14696
14697         set_persistent_param_and_check client "jobid_var" \
14698                 "$FSNAME.sys.jobid_var" $new_jobenv
14699 }
14700
14701 test_205() { # Job stats
14702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14703         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
14704                 skip "Need MDS version with at least 2.7.1"
14705         remote_mgs_nodsh && skip "remote MGS with nodsh"
14706         remote_mds_nodsh && skip "remote MDS with nodsh"
14707         remote_ost_nodsh && skip "remote OST with nodsh"
14708         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
14709                 skip "Server doesn't support jobstats"
14710         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
14711
14712         local old_jobenv=$($LCTL get_param -n jobid_var)
14713         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
14714
14715         if [[ $PERM_CMD == *"set_param -P"* ]]; then
14716                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
14717         else
14718                 stack_trap "do_facet mgs $PERM_CMD \
14719                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
14720         fi
14721         changelog_register
14722
14723         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
14724                                 mdt.*.job_cleanup_interval | head -n 1)
14725         local new_interval=5
14726         do_facet $SINGLEMDS \
14727                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
14728         stack_trap "do_facet $SINGLEMDS \
14729                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
14730         local start=$SECONDS
14731
14732         local cmd
14733         # mkdir
14734         cmd="mkdir $DIR/$tdir"
14735         verify_jobstats "$cmd" "$SINGLEMDS"
14736         # rmdir
14737         cmd="rmdir $DIR/$tdir"
14738         verify_jobstats "$cmd" "$SINGLEMDS"
14739         # mkdir on secondary MDT
14740         if [ $MDSCOUNT -gt 1 ]; then
14741                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
14742                 verify_jobstats "$cmd" "mds2"
14743         fi
14744         # mknod
14745         cmd="mknod $DIR/$tfile c 1 3"
14746         verify_jobstats "$cmd" "$SINGLEMDS"
14747         # unlink
14748         cmd="rm -f $DIR/$tfile"
14749         verify_jobstats "$cmd" "$SINGLEMDS"
14750         # create all files on OST0000 so verify_jobstats can find OST stats
14751         # open & close
14752         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
14753         verify_jobstats "$cmd" "$SINGLEMDS"
14754         # setattr
14755         cmd="touch $DIR/$tfile"
14756         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14757         # write
14758         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
14759         verify_jobstats "$cmd" "ost1"
14760         # read
14761         cancel_lru_locks osc
14762         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
14763         verify_jobstats "$cmd" "ost1"
14764         # truncate
14765         cmd="$TRUNCATE $DIR/$tfile 0"
14766         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14767         # rename
14768         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
14769         verify_jobstats "$cmd" "$SINGLEMDS"
14770         # jobstats expiry - sleep until old stats should be expired
14771         local left=$((new_interval + 5 - (SECONDS - start)))
14772         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
14773                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
14774                         "0" $left
14775         cmd="mkdir $DIR/$tdir.expire"
14776         verify_jobstats "$cmd" "$SINGLEMDS"
14777         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
14778             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
14779
14780         # Ensure that jobid are present in changelog (if supported by MDS)
14781         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
14782                 changelog_dump | tail -10
14783                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
14784                 [ $jobids -eq 9 ] ||
14785                         error "Wrong changelog jobid count $jobids != 9"
14786
14787                 # LU-5862
14788                 JOBENV="disable"
14789                 jobstats_set $JOBENV
14790                 touch $DIR/$tfile
14791                 changelog_dump | grep $tfile
14792                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
14793                 [ $jobids -eq 0 ] ||
14794                         error "Unexpected jobids when jobid_var=$JOBENV"
14795         fi
14796
14797         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
14798         JOBENV="JOBCOMPLEX"
14799         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
14800
14801         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
14802 }
14803 run_test 205 "Verify job stats"
14804
14805 # LU-1480, LU-1773 and LU-1657
14806 test_206() {
14807         mkdir -p $DIR/$tdir
14808         $LFS setstripe -c -1 $DIR/$tdir
14809 #define OBD_FAIL_LOV_INIT 0x1403
14810         $LCTL set_param fail_loc=0xa0001403
14811         $LCTL set_param fail_val=1
14812         touch $DIR/$tdir/$tfile || true
14813 }
14814 run_test 206 "fail lov_init_raid0() doesn't lbug"
14815
14816 test_207a() {
14817         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14818         local fsz=`stat -c %s $DIR/$tfile`
14819         cancel_lru_locks mdc
14820
14821         # do not return layout in getattr intent
14822 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
14823         $LCTL set_param fail_loc=0x170
14824         local sz=`stat -c %s $DIR/$tfile`
14825
14826         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
14827
14828         rm -rf $DIR/$tfile
14829 }
14830 run_test 207a "can refresh layout at glimpse"
14831
14832 test_207b() {
14833         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14834         local cksum=`md5sum $DIR/$tfile`
14835         local fsz=`stat -c %s $DIR/$tfile`
14836         cancel_lru_locks mdc
14837         cancel_lru_locks osc
14838
14839         # do not return layout in getattr intent
14840 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
14841         $LCTL set_param fail_loc=0x171
14842
14843         # it will refresh layout after the file is opened but before read issues
14844         echo checksum is "$cksum"
14845         echo "$cksum" |md5sum -c --quiet || error "file differs"
14846
14847         rm -rf $DIR/$tfile
14848 }
14849 run_test 207b "can refresh layout at open"
14850
14851 test_208() {
14852         # FIXME: in this test suite, only RD lease is used. This is okay
14853         # for now as only exclusive open is supported. After generic lease
14854         # is done, this test suite should be revised. - Jinshan
14855
14856         remote_mds_nodsh && skip "remote MDS with nodsh"
14857         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
14858                 skip "Need MDS version at least 2.4.52"
14859
14860         echo "==== test 1: verify get lease work"
14861         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
14862
14863         echo "==== test 2: verify lease can be broken by upcoming open"
14864         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14865         local PID=$!
14866         sleep 1
14867
14868         $MULTIOP $DIR/$tfile oO_RDONLY:c
14869         kill -USR1 $PID && wait $PID || error "break lease error"
14870
14871         echo "==== test 3: verify lease can't be granted if an open already exists"
14872         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
14873         local PID=$!
14874         sleep 1
14875
14876         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
14877         kill -USR1 $PID && wait $PID || error "open file error"
14878
14879         echo "==== test 4: lease can sustain over recovery"
14880         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
14881         PID=$!
14882         sleep 1
14883
14884         fail mds1
14885
14886         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
14887
14888         echo "==== test 5: lease broken can't be regained by replay"
14889         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14890         PID=$!
14891         sleep 1
14892
14893         # open file to break lease and then recovery
14894         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
14895         fail mds1
14896
14897         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
14898
14899         rm -f $DIR/$tfile
14900 }
14901 run_test 208 "Exclusive open"
14902
14903 test_209() {
14904         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
14905                 skip_env "must have disp_stripe"
14906
14907         touch $DIR/$tfile
14908         sync; sleep 5; sync;
14909
14910         echo 3 > /proc/sys/vm/drop_caches
14911         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14912
14913         # open/close 500 times
14914         for i in $(seq 500); do
14915                 cat $DIR/$tfile
14916         done
14917
14918         echo 3 > /proc/sys/vm/drop_caches
14919         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14920
14921         echo "before: $req_before, after: $req_after"
14922         [ $((req_after - req_before)) -ge 300 ] &&
14923                 error "open/close requests are not freed"
14924         return 0
14925 }
14926 run_test 209 "read-only open/close requests should be freed promptly"
14927
14928 test_212() {
14929         size=`date +%s`
14930         size=$((size % 8192 + 1))
14931         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
14932         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
14933         rm -f $DIR/f212 $DIR/f212.xyz
14934 }
14935 run_test 212 "Sendfile test ============================================"
14936
14937 test_213() {
14938         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
14939         cancel_lru_locks osc
14940         lctl set_param fail_loc=0x8000040f
14941         # generate a read lock
14942         cat $DIR/$tfile > /dev/null
14943         # write to the file, it will try to cancel the above read lock.
14944         cat /etc/hosts >> $DIR/$tfile
14945 }
14946 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
14947
14948 test_214() { # for bug 20133
14949         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
14950         for (( i=0; i < 340; i++ )) ; do
14951                 touch $DIR/$tdir/d214c/a$i
14952         done
14953
14954         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
14955         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
14956         ls $DIR/d214c || error "ls $DIR/d214c failed"
14957         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
14958         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
14959 }
14960 run_test 214 "hash-indexed directory test - bug 20133"
14961
14962 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
14963 create_lnet_proc_files() {
14964         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
14965 }
14966
14967 # counterpart of create_lnet_proc_files
14968 remove_lnet_proc_files() {
14969         rm -f $TMP/lnet_$1.sys
14970 }
14971
14972 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14973 # 3rd arg as regexp for body
14974 check_lnet_proc_stats() {
14975         local l=$(cat "$TMP/lnet_$1" |wc -l)
14976         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
14977
14978         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
14979 }
14980
14981 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14982 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
14983 # optional and can be regexp for 2nd line (lnet.routes case)
14984 check_lnet_proc_entry() {
14985         local blp=2          # blp stands for 'position of 1st line of body'
14986         [ -z "$5" ] || blp=3 # lnet.routes case
14987
14988         local l=$(cat "$TMP/lnet_$1" |wc -l)
14989         # subtracting one from $blp because the body can be empty
14990         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
14991
14992         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
14993                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
14994
14995         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
14996                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
14997
14998         # bail out if any unexpected line happened
14999         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
15000         [ "$?" != 0 ] || error "$2 misformatted"
15001 }
15002
15003 test_215() { # for bugs 18102, 21079, 21517
15004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15005
15006         local N='(0|[1-9][0-9]*)'       # non-negative numeric
15007         local P='[1-9][0-9]*'           # positive numeric
15008         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
15009         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
15010         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
15011         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
15012
15013         local L1 # regexp for 1st line
15014         local L2 # regexp for 2nd line (optional)
15015         local BR # regexp for the rest (body)
15016
15017         # lnet.stats should look as 11 space-separated non-negative numerics
15018         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
15019         create_lnet_proc_files "stats"
15020         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
15021         remove_lnet_proc_files "stats"
15022
15023         # lnet.routes should look like this:
15024         # Routing disabled/enabled
15025         # net hops priority state router
15026         # where net is a string like tcp0, hops > 0, priority >= 0,
15027         # state is up/down,
15028         # router is a string like 192.168.1.1@tcp2
15029         L1="^Routing (disabled|enabled)$"
15030         L2="^net +hops +priority +state +router$"
15031         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
15032         create_lnet_proc_files "routes"
15033         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
15034         remove_lnet_proc_files "routes"
15035
15036         # lnet.routers should look like this:
15037         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
15038         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
15039         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
15040         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
15041         L1="^ref +rtr_ref +alive_cnt +state +last_ping +ping_sent +deadline +down_ni +router$"
15042         BR="^$P +$P +$N +(up|down) +$N +(0|1) +$I +$I +$NID$"
15043         create_lnet_proc_files "routers"
15044         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
15045         remove_lnet_proc_files "routers"
15046
15047         # lnet.peers should look like this:
15048         # nid refs state last max rtr min tx min queue
15049         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
15050         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
15051         # numeric (0 or >0 or <0), queue >= 0.
15052         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
15053         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
15054         create_lnet_proc_files "peers"
15055         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
15056         remove_lnet_proc_files "peers"
15057
15058         # lnet.buffers  should look like this:
15059         # pages count credits min
15060         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
15061         L1="^pages +count +credits +min$"
15062         BR="^ +$N +$N +$I +$I$"
15063         create_lnet_proc_files "buffers"
15064         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
15065         remove_lnet_proc_files "buffers"
15066
15067         # lnet.nis should look like this:
15068         # nid status alive refs peer rtr max tx min
15069         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
15070         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
15071         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
15072         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
15073         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
15074         create_lnet_proc_files "nis"
15075         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
15076         remove_lnet_proc_files "nis"
15077
15078         # can we successfully write to lnet.stats?
15079         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
15080 }
15081 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
15082
15083 test_216() { # bug 20317
15084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15085         remote_ost_nodsh && skip "remote OST with nodsh"
15086
15087         local node
15088         local facets=$(get_facets OST)
15089         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15090
15091         save_lustre_params client "osc.*.contention_seconds" > $p
15092         save_lustre_params $facets \
15093                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
15094         save_lustre_params $facets \
15095                 "ldlm.namespaces.filter-*.contended_locks" >> $p
15096         save_lustre_params $facets \
15097                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
15098         clear_stats osc.*.osc_stats
15099
15100         # agressive lockless i/o settings
15101         do_nodes $(comma_list $(osts_nodes)) \
15102                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
15103                         ldlm.namespaces.filter-*.contended_locks=0 \
15104                         ldlm.namespaces.filter-*.contention_seconds=60"
15105         lctl set_param -n osc.*.contention_seconds=60
15106
15107         $DIRECTIO write $DIR/$tfile 0 10 4096
15108         $CHECKSTAT -s 40960 $DIR/$tfile
15109
15110         # disable lockless i/o
15111         do_nodes $(comma_list $(osts_nodes)) \
15112                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
15113                         ldlm.namespaces.filter-*.contended_locks=32 \
15114                         ldlm.namespaces.filter-*.contention_seconds=0"
15115         lctl set_param -n osc.*.contention_seconds=0
15116         clear_stats osc.*.osc_stats
15117
15118         dd if=/dev/zero of=$DIR/$tfile count=0
15119         $CHECKSTAT -s 0 $DIR/$tfile
15120
15121         restore_lustre_params <$p
15122         rm -f $p
15123         rm $DIR/$tfile
15124 }
15125 run_test 216 "check lockless direct write updates file size and kms correctly"
15126
15127 test_217() { # bug 22430
15128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15129
15130         local node
15131         local nid
15132
15133         for node in $(nodes_list); do
15134                 nid=$(host_nids_address $node $NETTYPE)
15135                 if [[ $nid = *-* ]] ; then
15136                         echo "lctl ping $(h2nettype $nid)"
15137                         lctl ping $(h2nettype $nid)
15138                 else
15139                         echo "skipping $node (no hyphen detected)"
15140                 fi
15141         done
15142 }
15143 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
15144
15145 test_218() {
15146        # do directio so as not to populate the page cache
15147        log "creating a 10 Mb file"
15148        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15149        log "starting reads"
15150        dd if=$DIR/$tfile of=/dev/null bs=4096 &
15151        log "truncating the file"
15152        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15153        log "killing dd"
15154        kill %+ || true # reads might have finished
15155        echo "wait until dd is finished"
15156        wait
15157        log "removing the temporary file"
15158        rm -rf $DIR/$tfile || error "tmp file removal failed"
15159 }
15160 run_test 218 "parallel read and truncate should not deadlock"
15161
15162 test_219() {
15163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15164
15165         # write one partial page
15166         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
15167         # set no grant so vvp_io_commit_write will do sync write
15168         $LCTL set_param fail_loc=0x411
15169         # write a full page at the end of file
15170         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
15171
15172         $LCTL set_param fail_loc=0
15173         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
15174         $LCTL set_param fail_loc=0x411
15175         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
15176
15177         # LU-4201
15178         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
15179         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
15180 }
15181 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
15182
15183 test_220() { #LU-325
15184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15185         remote_ost_nodsh && skip "remote OST with nodsh"
15186         remote_mds_nodsh && skip "remote MDS with nodsh"
15187         remote_mgs_nodsh && skip "remote MGS with nodsh"
15188
15189         local OSTIDX=0
15190
15191         # create on MDT0000 so the last_id and next_id are correct
15192         mkdir $DIR/$tdir
15193         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
15194         OST=${OST%_UUID}
15195
15196         # on the mdt's osc
15197         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
15198         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
15199                         osc.$mdtosc_proc1.prealloc_last_id)
15200         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
15201                         osc.$mdtosc_proc1.prealloc_next_id)
15202
15203         $LFS df -i
15204
15205         if ! combined_mgs_mds ; then
15206                 mount_mgs_client
15207         fi
15208
15209         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
15210         #define OBD_FAIL_OST_ENOINO              0x229
15211         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
15212         create_pool $FSNAME.$TESTNAME || return 1
15213         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
15214
15215         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
15216
15217         MDSOBJS=$((last_id - next_id))
15218         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
15219
15220         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
15221         echo "OST still has $count kbytes free"
15222
15223         echo "create $MDSOBJS files @next_id..."
15224         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
15225
15226         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15227                         osc.$mdtosc_proc1.prealloc_last_id)
15228         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15229                         osc.$mdtosc_proc1.prealloc_next_id)
15230
15231         echo "after creation, last_id=$last_id2, next_id=$next_id2"
15232         $LFS df -i
15233
15234         echo "cleanup..."
15235
15236         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
15237         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
15238
15239         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
15240                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
15241         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
15242                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
15243         echo "unlink $MDSOBJS files @$next_id..."
15244         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
15245
15246         if ! combined_mgs_mds ; then
15247                 umount_mgs_client
15248         fi
15249 }
15250 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
15251
15252 test_221() {
15253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15254
15255         dd if=`which date` of=$MOUNT/date oflag=sync
15256         chmod +x $MOUNT/date
15257
15258         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
15259         $LCTL set_param fail_loc=0x80001401
15260
15261         $MOUNT/date > /dev/null
15262         rm -f $MOUNT/date
15263 }
15264 run_test 221 "make sure fault and truncate race to not cause OOM"
15265
15266 test_222a () {
15267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15268
15269         rm -rf $DIR/$tdir
15270         test_mkdir $DIR/$tdir
15271         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15272         createmany -o $DIR/$tdir/$tfile 10
15273         cancel_lru_locks mdc
15274         cancel_lru_locks osc
15275         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15276         $LCTL set_param fail_loc=0x31a
15277         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
15278         $LCTL set_param fail_loc=0
15279         rm -r $DIR/$tdir
15280 }
15281 run_test 222a "AGL for ls should not trigger CLIO lock failure"
15282
15283 test_222b () {
15284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15285
15286         rm -rf $DIR/$tdir
15287         test_mkdir $DIR/$tdir
15288         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15289         createmany -o $DIR/$tdir/$tfile 10
15290         cancel_lru_locks mdc
15291         cancel_lru_locks osc
15292         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15293         $LCTL set_param fail_loc=0x31a
15294         rm -r $DIR/$tdir || error "AGL for rmdir failed"
15295         $LCTL set_param fail_loc=0
15296 }
15297 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
15298
15299 test_223 () {
15300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15301
15302         rm -rf $DIR/$tdir
15303         test_mkdir $DIR/$tdir
15304         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15305         createmany -o $DIR/$tdir/$tfile 10
15306         cancel_lru_locks mdc
15307         cancel_lru_locks osc
15308         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
15309         $LCTL set_param fail_loc=0x31b
15310         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
15311         $LCTL set_param fail_loc=0
15312         rm -r $DIR/$tdir
15313 }
15314 run_test 223 "osc reenqueue if without AGL lock granted ======================="
15315
15316 test_224a() { # LU-1039, MRP-303
15317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15318
15319         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
15320         $LCTL set_param fail_loc=0x508
15321         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
15322         $LCTL set_param fail_loc=0
15323         df $DIR
15324 }
15325 run_test 224a "Don't panic on bulk IO failure"
15326
15327 test_224b() { # LU-1039, MRP-303
15328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15329
15330         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
15331         cancel_lru_locks osc
15332         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
15333         $LCTL set_param fail_loc=0x515
15334         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
15335         $LCTL set_param fail_loc=0
15336         df $DIR
15337 }
15338 run_test 224b "Don't panic on bulk IO failure"
15339
15340 test_224c() { # LU-6441
15341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15342         remote_mds_nodsh && skip "remote MDS with nodsh"
15343
15344         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15345         save_writethrough $p
15346         set_cache writethrough on
15347
15348         local pages_per_rpc=$($LCTL get_param \
15349                                 osc.*.max_pages_per_rpc)
15350         local at_max=$($LCTL get_param -n at_max)
15351         local timeout=$($LCTL get_param -n timeout)
15352         local test_at="at_max"
15353         local param_at="$FSNAME.sys.at_max"
15354         local test_timeout="timeout"
15355         local param_timeout="$FSNAME.sys.timeout"
15356
15357         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
15358
15359         set_persistent_param_and_check client "$test_at" "$param_at" 0
15360         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
15361
15362         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
15363         do_facet ost1 "$LCTL set_param fail_loc=0x520"
15364         $LFS setstripe -c 1 -i 0 $DIR/$tfile
15365         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
15366         sync
15367         do_facet ost1 "$LCTL set_param fail_loc=0"
15368
15369         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
15370         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
15371                 $timeout
15372
15373         $LCTL set_param -n $pages_per_rpc
15374         restore_lustre_params < $p
15375         rm -f $p
15376 }
15377 run_test 224c "Don't hang if one of md lost during large bulk RPC"
15378
15379 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
15380 test_225a () {
15381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15382         if [ -z ${MDSSURVEY} ]; then
15383                 skip_env "mds-survey not found"
15384         fi
15385         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
15386                 skip "Need MDS version at least 2.2.51"
15387
15388         local mds=$(facet_host $SINGLEMDS)
15389         local target=$(do_nodes $mds 'lctl dl' |
15390                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
15391
15392         local cmd1="file_count=1000 thrhi=4"
15393         local cmd2="dir_count=2 layer=mdd stripe_count=0"
15394         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
15395         local cmd="$cmd1 $cmd2 $cmd3"
15396
15397         rm -f ${TMP}/mds_survey*
15398         echo + $cmd
15399         eval $cmd || error "mds-survey with zero-stripe failed"
15400         cat ${TMP}/mds_survey*
15401         rm -f ${TMP}/mds_survey*
15402 }
15403 run_test 225a "Metadata survey sanity with zero-stripe"
15404
15405 test_225b () {
15406         if [ -z ${MDSSURVEY} ]; then
15407                 skip_env "mds-survey not found"
15408         fi
15409         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
15410                 skip "Need MDS version at least 2.2.51"
15411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15412         remote_mds_nodsh && skip "remote MDS with nodsh"
15413         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
15414                 skip_env "Need to mount OST to test"
15415         fi
15416
15417         local mds=$(facet_host $SINGLEMDS)
15418         local target=$(do_nodes $mds 'lctl dl' |
15419                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
15420
15421         local cmd1="file_count=1000 thrhi=4"
15422         local cmd2="dir_count=2 layer=mdd stripe_count=1"
15423         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
15424         local cmd="$cmd1 $cmd2 $cmd3"
15425
15426         rm -f ${TMP}/mds_survey*
15427         echo + $cmd
15428         eval $cmd || error "mds-survey with stripe_count failed"
15429         cat ${TMP}/mds_survey*
15430         rm -f ${TMP}/mds_survey*
15431 }
15432 run_test 225b "Metadata survey sanity with stripe_count = 1"
15433
15434 mcreate_path2fid () {
15435         local mode=$1
15436         local major=$2
15437         local minor=$3
15438         local name=$4
15439         local desc=$5
15440         local path=$DIR/$tdir/$name
15441         local fid
15442         local rc
15443         local fid_path
15444
15445         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
15446                 error "cannot create $desc"
15447
15448         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
15449         rc=$?
15450         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
15451
15452         fid_path=$($LFS fid2path $MOUNT $fid)
15453         rc=$?
15454         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
15455
15456         [ "$path" == "$fid_path" ] ||
15457                 error "fid2path returned $fid_path, expected $path"
15458
15459         echo "pass with $path and $fid"
15460 }
15461
15462 test_226a () {
15463         rm -rf $DIR/$tdir
15464         mkdir -p $DIR/$tdir
15465
15466         mcreate_path2fid 0010666 0 0 fifo "FIFO"
15467         mcreate_path2fid 0020666 1 3 null "character special file (null)"
15468         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
15469         mcreate_path2fid 0040666 0 0 dir "directory"
15470         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
15471         mcreate_path2fid 0100666 0 0 file "regular file"
15472         mcreate_path2fid 0120666 0 0 link "symbolic link"
15473         mcreate_path2fid 0140666 0 0 sock "socket"
15474 }
15475 run_test 226a "call path2fid and fid2path on files of all type"
15476
15477 test_226b () {
15478         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15479
15480         local MDTIDX=1
15481
15482         rm -rf $DIR/$tdir
15483         mkdir -p $DIR/$tdir
15484         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
15485                 error "create remote directory failed"
15486         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
15487         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
15488                                 "character special file (null)"
15489         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
15490                                 "character special file (no device)"
15491         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
15492         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
15493                                 "block special file (loop)"
15494         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
15495         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
15496         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
15497 }
15498 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
15499
15500 # LU-1299 Executing or running ldd on a truncated executable does not
15501 # cause an out-of-memory condition.
15502 test_227() {
15503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15504         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
15505
15506         dd if=$(which date) of=$MOUNT/date bs=1k count=1
15507         chmod +x $MOUNT/date
15508
15509         $MOUNT/date > /dev/null
15510         ldd $MOUNT/date > /dev/null
15511         rm -f $MOUNT/date
15512 }
15513 run_test 227 "running truncated executable does not cause OOM"
15514
15515 # LU-1512 try to reuse idle OI blocks
15516 test_228a() {
15517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15518         remote_mds_nodsh && skip "remote MDS with nodsh"
15519         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15520
15521         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15522         local myDIR=$DIR/$tdir
15523
15524         mkdir -p $myDIR
15525         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15526         $LCTL set_param fail_loc=0x80001002
15527         createmany -o $myDIR/t- 10000
15528         $LCTL set_param fail_loc=0
15529         # The guard is current the largest FID holder
15530         touch $myDIR/guard
15531         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15532                     tr -d '[')
15533         local IDX=$(($SEQ % 64))
15534
15535         do_facet $SINGLEMDS sync
15536         # Make sure journal flushed.
15537         sleep 6
15538         local blk1=$(do_facet $SINGLEMDS \
15539                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15540                      grep Blockcount | awk '{print $4}')
15541
15542         # Remove old files, some OI blocks will become idle.
15543         unlinkmany $myDIR/t- 10000
15544         # Create new files, idle OI blocks should be reused.
15545         createmany -o $myDIR/t- 2000
15546         do_facet $SINGLEMDS sync
15547         # Make sure journal flushed.
15548         sleep 6
15549         local blk2=$(do_facet $SINGLEMDS \
15550                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15551                      grep Blockcount | awk '{print $4}')
15552
15553         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15554 }
15555 run_test 228a "try to reuse idle OI blocks"
15556
15557 test_228b() {
15558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15559         remote_mds_nodsh && skip "remote MDS with nodsh"
15560         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15561
15562         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15563         local myDIR=$DIR/$tdir
15564
15565         mkdir -p $myDIR
15566         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15567         $LCTL set_param fail_loc=0x80001002
15568         createmany -o $myDIR/t- 10000
15569         $LCTL set_param fail_loc=0
15570         # The guard is current the largest FID holder
15571         touch $myDIR/guard
15572         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15573                     tr -d '[')
15574         local IDX=$(($SEQ % 64))
15575
15576         do_facet $SINGLEMDS sync
15577         # Make sure journal flushed.
15578         sleep 6
15579         local blk1=$(do_facet $SINGLEMDS \
15580                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15581                      grep Blockcount | awk '{print $4}')
15582
15583         # Remove old files, some OI blocks will become idle.
15584         unlinkmany $myDIR/t- 10000
15585
15586         # stop the MDT
15587         stop $SINGLEMDS || error "Fail to stop MDT."
15588         # remount the MDT
15589         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
15590
15591         df $MOUNT || error "Fail to df."
15592         # Create new files, idle OI blocks should be reused.
15593         createmany -o $myDIR/t- 2000
15594         do_facet $SINGLEMDS sync
15595         # Make sure journal flushed.
15596         sleep 6
15597         local blk2=$(do_facet $SINGLEMDS \
15598                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15599                      grep Blockcount | awk '{print $4}')
15600
15601         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15602 }
15603 run_test 228b "idle OI blocks can be reused after MDT restart"
15604
15605 #LU-1881
15606 test_228c() {
15607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15608         remote_mds_nodsh && skip "remote MDS with nodsh"
15609         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15610
15611         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15612         local myDIR=$DIR/$tdir
15613
15614         mkdir -p $myDIR
15615         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15616         $LCTL set_param fail_loc=0x80001002
15617         # 20000 files can guarantee there are index nodes in the OI file
15618         createmany -o $myDIR/t- 20000
15619         $LCTL set_param fail_loc=0
15620         # The guard is current the largest FID holder
15621         touch $myDIR/guard
15622         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15623                     tr -d '[')
15624         local IDX=$(($SEQ % 64))
15625
15626         do_facet $SINGLEMDS sync
15627         # Make sure journal flushed.
15628         sleep 6
15629         local blk1=$(do_facet $SINGLEMDS \
15630                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15631                      grep Blockcount | awk '{print $4}')
15632
15633         # Remove old files, some OI blocks will become idle.
15634         unlinkmany $myDIR/t- 20000
15635         rm -f $myDIR/guard
15636         # The OI file should become empty now
15637
15638         # Create new files, idle OI blocks should be reused.
15639         createmany -o $myDIR/t- 2000
15640         do_facet $SINGLEMDS sync
15641         # Make sure journal flushed.
15642         sleep 6
15643         local blk2=$(do_facet $SINGLEMDS \
15644                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15645                      grep Blockcount | awk '{print $4}')
15646
15647         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15648 }
15649 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
15650
15651 test_229() { # LU-2482, LU-3448
15652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15653         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
15654         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
15655                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
15656
15657         rm -f $DIR/$tfile
15658
15659         # Create a file with a released layout and stripe count 2.
15660         $MULTIOP $DIR/$tfile H2c ||
15661                 error "failed to create file with released layout"
15662
15663         $LFS getstripe -v $DIR/$tfile
15664
15665         local pattern=$($LFS getstripe -L $DIR/$tfile)
15666         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
15667
15668         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
15669                 error "getstripe"
15670         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
15671         stat $DIR/$tfile || error "failed to stat released file"
15672
15673         chown $RUNAS_ID $DIR/$tfile ||
15674                 error "chown $RUNAS_ID $DIR/$tfile failed"
15675
15676         chgrp $RUNAS_ID $DIR/$tfile ||
15677                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
15678
15679         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
15680         rm $DIR/$tfile || error "failed to remove released file"
15681 }
15682 run_test 229 "getstripe/stat/rm/attr changes work on released files"
15683
15684 test_230a() {
15685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15686         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15687         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15688                 skip "Need MDS version at least 2.11.52"
15689
15690         local MDTIDX=1
15691
15692         test_mkdir $DIR/$tdir
15693         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
15694         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
15695         [ $mdt_idx -ne 0 ] &&
15696                 error "create local directory on wrong MDT $mdt_idx"
15697
15698         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
15699                         error "create remote directory failed"
15700         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
15701         [ $mdt_idx -ne $MDTIDX ] &&
15702                 error "create remote directory on wrong MDT $mdt_idx"
15703
15704         createmany -o $DIR/$tdir/test_230/t- 10 ||
15705                 error "create files on remote directory failed"
15706         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
15707         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
15708         rm -r $DIR/$tdir || error "unlink remote directory failed"
15709 }
15710 run_test 230a "Create remote directory and files under the remote directory"
15711
15712 test_230b() {
15713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15714         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15715         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15716                 skip "Need MDS version at least 2.11.52"
15717
15718         local MDTIDX=1
15719         local mdt_index
15720         local i
15721         local file
15722         local pid
15723         local stripe_count
15724         local migrate_dir=$DIR/$tdir/migrate_dir
15725         local other_dir=$DIR/$tdir/other_dir
15726
15727         test_mkdir $DIR/$tdir
15728         test_mkdir -i0 -c1 $migrate_dir
15729         test_mkdir -i0 -c1 $other_dir
15730         for ((i=0; i<10; i++)); do
15731                 mkdir -p $migrate_dir/dir_${i}
15732                 createmany -o $migrate_dir/dir_${i}/f 10 ||
15733                         error "create files under remote dir failed $i"
15734         done
15735
15736         cp /etc/passwd $migrate_dir/$tfile
15737         cp /etc/passwd $other_dir/$tfile
15738         chattr +SAD $migrate_dir
15739         chattr +SAD $migrate_dir/$tfile
15740
15741         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15742         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15743         local old_dir_mode=$(stat -c%f $migrate_dir)
15744         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
15745
15746         mkdir -p $migrate_dir/dir_default_stripe2
15747         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
15748         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
15749
15750         mkdir -p $other_dir
15751         ln $migrate_dir/$tfile $other_dir/luna
15752         ln $migrate_dir/$tfile $migrate_dir/sofia
15753         ln $other_dir/$tfile $migrate_dir/david
15754         ln -s $migrate_dir/$tfile $other_dir/zachary
15755         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
15756         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
15757
15758         $LFS migrate -m $MDTIDX $migrate_dir ||
15759                 error "fails on migrating remote dir to MDT1"
15760
15761         echo "migratate to MDT1, then checking.."
15762         for ((i = 0; i < 10; i++)); do
15763                 for file in $(find $migrate_dir/dir_${i}); do
15764                         mdt_index=$($LFS getstripe -m $file)
15765                         [ $mdt_index == $MDTIDX ] ||
15766                                 error "$file is not on MDT${MDTIDX}"
15767                 done
15768         done
15769
15770         # the multiple link file should still in MDT0
15771         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
15772         [ $mdt_index == 0 ] ||
15773                 error "$file is not on MDT${MDTIDX}"
15774
15775         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15776         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15777                 error " expect $old_dir_flag get $new_dir_flag"
15778
15779         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15780         [ "$old_file_flag" = "$new_file_flag" ] ||
15781                 error " expect $old_file_flag get $new_file_flag"
15782
15783         local new_dir_mode=$(stat -c%f $migrate_dir)
15784         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15785                 error "expect mode $old_dir_mode get $new_dir_mode"
15786
15787         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15788         [ "$old_file_mode" = "$new_file_mode" ] ||
15789                 error "expect mode $old_file_mode get $new_file_mode"
15790
15791         diff /etc/passwd $migrate_dir/$tfile ||
15792                 error "$tfile different after migration"
15793
15794         diff /etc/passwd $other_dir/luna ||
15795                 error "luna different after migration"
15796
15797         diff /etc/passwd $migrate_dir/sofia ||
15798                 error "sofia different after migration"
15799
15800         diff /etc/passwd $migrate_dir/david ||
15801                 error "david different after migration"
15802
15803         diff /etc/passwd $other_dir/zachary ||
15804                 error "zachary different after migration"
15805
15806         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15807                 error "${tfile}_ln different after migration"
15808
15809         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15810                 error "${tfile}_ln_other different after migration"
15811
15812         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
15813         [ $stripe_count = 2 ] ||
15814                 error "dir strpe_count $d != 2 after migration."
15815
15816         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
15817         [ $stripe_count = 2 ] ||
15818                 error "file strpe_count $d != 2 after migration."
15819
15820         #migrate back to MDT0
15821         MDTIDX=0
15822
15823         $LFS migrate -m $MDTIDX $migrate_dir ||
15824                 error "fails on migrating remote dir to MDT0"
15825
15826         echo "migrate back to MDT0, checking.."
15827         for file in $(find $migrate_dir); do
15828                 mdt_index=$($LFS getstripe -m $file)
15829                 [ $mdt_index == $MDTIDX ] ||
15830                         error "$file is not on MDT${MDTIDX}"
15831         done
15832
15833         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15834         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15835                 error " expect $old_dir_flag get $new_dir_flag"
15836
15837         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15838         [ "$old_file_flag" = "$new_file_flag" ] ||
15839                 error " expect $old_file_flag get $new_file_flag"
15840
15841         local new_dir_mode=$(stat -c%f $migrate_dir)
15842         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15843                 error "expect mode $old_dir_mode get $new_dir_mode"
15844
15845         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15846         [ "$old_file_mode" = "$new_file_mode" ] ||
15847                 error "expect mode $old_file_mode get $new_file_mode"
15848
15849         diff /etc/passwd ${migrate_dir}/$tfile ||
15850                 error "$tfile different after migration"
15851
15852         diff /etc/passwd ${other_dir}/luna ||
15853                 error "luna different after migration"
15854
15855         diff /etc/passwd ${migrate_dir}/sofia ||
15856                 error "sofia different after migration"
15857
15858         diff /etc/passwd ${other_dir}/zachary ||
15859                 error "zachary different after migration"
15860
15861         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15862                 error "${tfile}_ln different after migration"
15863
15864         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15865                 error "${tfile}_ln_other different after migration"
15866
15867         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
15868         [ $stripe_count = 2 ] ||
15869                 error "dir strpe_count $d != 2 after migration."
15870
15871         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
15872         [ $stripe_count = 2 ] ||
15873                 error "file strpe_count $d != 2 after migration."
15874
15875         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15876 }
15877 run_test 230b "migrate directory"
15878
15879 test_230c() {
15880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15881         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15882         remote_mds_nodsh && skip "remote MDS with nodsh"
15883         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15884                 skip "Need MDS version at least 2.11.52"
15885
15886         local MDTIDX=1
15887         local total=3
15888         local mdt_index
15889         local file
15890         local migrate_dir=$DIR/$tdir/migrate_dir
15891
15892         #If migrating directory fails in the middle, all entries of
15893         #the directory is still accessiable.
15894         test_mkdir $DIR/$tdir
15895         test_mkdir -i0 -c1 $migrate_dir
15896         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
15897         stat $migrate_dir
15898         createmany -o $migrate_dir/f $total ||
15899                 error "create files under ${migrate_dir} failed"
15900
15901         # fail after migrating top dir, and this will fail only once, so the
15902         # first sub file migration will fail (currently f3), others succeed.
15903         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
15904         do_facet mds1 lctl set_param fail_loc=0x1801
15905         local t=$(ls $migrate_dir | wc -l)
15906         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
15907                 error "migrate should fail"
15908         local u=$(ls $migrate_dir | wc -l)
15909         [ "$u" == "$t" ] || error "$u != $t during migration"
15910
15911         # add new dir/file should succeed
15912         mkdir $migrate_dir/dir ||
15913                 error "mkdir failed under migrating directory"
15914         touch $migrate_dir/file ||
15915                 error "create file failed under migrating directory"
15916
15917         # add file with existing name should fail
15918         for file in $migrate_dir/f*; do
15919                 stat $file > /dev/null || error "stat $file failed"
15920                 $OPENFILE -f O_CREAT:O_EXCL $file &&
15921                         error "open(O_CREAT|O_EXCL) $file should fail"
15922                 $MULTIOP $file m && error "create $file should fail"
15923                 touch $DIR/$tdir/remote_dir/$tfile ||
15924                         error "touch $tfile failed"
15925                 ln $DIR/$tdir/remote_dir/$tfile $file &&
15926                         error "link $file should fail"
15927                 mdt_index=$($LFS getstripe -m $file)
15928                 if [ $mdt_index == 0 ]; then
15929                         # file failed to migrate is not allowed to rename to
15930                         mv $DIR/$tdir/remote_dir/$tfile $file &&
15931                                 error "rename to $file should fail"
15932                 else
15933                         mv $DIR/$tdir/remote_dir/$tfile $file ||
15934                                 error "rename to $file failed"
15935                 fi
15936                 echo hello >> $file || error "write $file failed"
15937         done
15938
15939         # resume migration with different options should fail
15940         $LFS migrate -m 0 $migrate_dir &&
15941                 error "migrate -m 0 $migrate_dir should fail"
15942
15943         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
15944                 error "migrate -c 2 $migrate_dir should fail"
15945
15946         # resume migration should succeed
15947         $LFS migrate -m $MDTIDX $migrate_dir ||
15948                 error "migrate $migrate_dir failed"
15949
15950         echo "Finish migration, then checking.."
15951         for file in $(find $migrate_dir); do
15952                 mdt_index=$($LFS getstripe -m $file)
15953                 [ $mdt_index == $MDTIDX ] ||
15954                         error "$file is not on MDT${MDTIDX}"
15955         done
15956
15957         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15958 }
15959 run_test 230c "check directory accessiblity if migration failed"
15960
15961 test_230d() {
15962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15963         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15964         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15965                 skip "Need MDS version at least 2.11.52"
15966         # LU-11235
15967         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
15968
15969         local migrate_dir=$DIR/$tdir/migrate_dir
15970         local old_index
15971         local new_index
15972         local old_count
15973         local new_count
15974         local new_hash
15975         local mdt_index
15976         local i
15977         local j
15978
15979         old_index=$((RANDOM % MDSCOUNT))
15980         old_count=$((MDSCOUNT - old_index))
15981         new_index=$((RANDOM % MDSCOUNT))
15982         new_count=$((MDSCOUNT - new_index))
15983         new_hash="all_char"
15984
15985         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
15986         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
15987
15988         test_mkdir $DIR/$tdir
15989         test_mkdir -i $old_index -c $old_count $migrate_dir
15990
15991         for ((i=0; i<100; i++)); do
15992                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
15993                 createmany -o $migrate_dir/dir_${i}/f 100 ||
15994                         error "create files under remote dir failed $i"
15995         done
15996
15997         echo -n "Migrate from MDT$old_index "
15998         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
15999         echo -n "to MDT$new_index"
16000         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
16001         echo
16002
16003         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
16004         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
16005                 error "migrate remote dir error"
16006
16007         echo "Finish migration, then checking.."
16008         for file in $(find $migrate_dir); do
16009                 mdt_index=$($LFS getstripe -m $file)
16010                 if [ $mdt_index -lt $new_index ] ||
16011                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
16012                         error "$file is on MDT$mdt_index"
16013                 fi
16014         done
16015
16016         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16017 }
16018 run_test 230d "check migrate big directory"
16019
16020 test_230e() {
16021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16022         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16023         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16024                 skip "Need MDS version at least 2.11.52"
16025
16026         local i
16027         local j
16028         local a_fid
16029         local b_fid
16030
16031         mkdir -p $DIR/$tdir
16032         mkdir $DIR/$tdir/migrate_dir
16033         mkdir $DIR/$tdir/other_dir
16034         touch $DIR/$tdir/migrate_dir/a
16035         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
16036         ls $DIR/$tdir/other_dir
16037
16038         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16039                 error "migrate dir fails"
16040
16041         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16042         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16043
16044         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16045         [ $mdt_index == 0 ] || error "a is not on MDT0"
16046
16047         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
16048                 error "migrate dir fails"
16049
16050         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
16051         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
16052
16053         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16054         [ $mdt_index == 1 ] || error "a is not on MDT1"
16055
16056         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
16057         [ $mdt_index == 1 ] || error "b is not on MDT1"
16058
16059         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16060         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
16061
16062         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
16063
16064         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16065 }
16066 run_test 230e "migrate mulitple local link files"
16067
16068 test_230f() {
16069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16070         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16071         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16072                 skip "Need MDS version at least 2.11.52"
16073
16074         local a_fid
16075         local ln_fid
16076
16077         mkdir -p $DIR/$tdir
16078         mkdir $DIR/$tdir/migrate_dir
16079         $LFS mkdir -i1 $DIR/$tdir/other_dir
16080         touch $DIR/$tdir/migrate_dir/a
16081         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
16082         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
16083         ls $DIR/$tdir/other_dir
16084
16085         # a should be migrated to MDT1, since no other links on MDT0
16086         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16087                 error "#1 migrate dir fails"
16088         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16089         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16090         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16091         [ $mdt_index == 1 ] || error "a is not on MDT1"
16092
16093         # a should stay on MDT1, because it is a mulitple link file
16094         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16095                 error "#2 migrate dir fails"
16096         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16097         [ $mdt_index == 1 ] || error "a is not on MDT1"
16098
16099         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16100                 error "#3 migrate dir fails"
16101
16102         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16103         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
16104         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
16105
16106         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
16107         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
16108
16109         # a should be migrated to MDT0, since no other links on MDT1
16110         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16111                 error "#4 migrate dir fails"
16112         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16113         [ $mdt_index == 0 ] || error "a is not on MDT0"
16114
16115         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16116 }
16117 run_test 230f "migrate mulitple remote link files"
16118
16119 test_230g() {
16120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16121         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16122         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16123                 skip "Need MDS version at least 2.11.52"
16124
16125         mkdir -p $DIR/$tdir/migrate_dir
16126
16127         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
16128                 error "migrating dir to non-exist MDT succeeds"
16129         true
16130 }
16131 run_test 230g "migrate dir to non-exist MDT"
16132
16133 test_230h() {
16134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16135         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16136         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16137                 skip "Need MDS version at least 2.11.52"
16138
16139         local mdt_index
16140
16141         mkdir -p $DIR/$tdir/migrate_dir
16142
16143         $LFS migrate -m1 $DIR &&
16144                 error "migrating mountpoint1 should fail"
16145
16146         $LFS migrate -m1 $DIR/$tdir/.. &&
16147                 error "migrating mountpoint2 should fail"
16148
16149         # same as mv
16150         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
16151                 error "migrating $tdir/migrate_dir/.. should fail"
16152
16153         true
16154 }
16155 run_test 230h "migrate .. and root"
16156
16157 test_230i() {
16158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16159         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16160         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16161                 skip "Need MDS version at least 2.11.52"
16162
16163         mkdir -p $DIR/$tdir/migrate_dir
16164
16165         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
16166                 error "migration fails with a tailing slash"
16167
16168         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
16169                 error "migration fails with two tailing slashes"
16170 }
16171 run_test 230i "lfs migrate -m tolerates trailing slashes"
16172
16173 test_230j() {
16174         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16175         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16176                 skip "Need MDS version at least 2.11.52"
16177
16178         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
16179         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
16180                 error "create $tfile failed"
16181         cat /etc/passwd > $DIR/$tdir/$tfile
16182
16183         $LFS migrate -m 1 $DIR/$tdir
16184
16185         cmp /etc/passwd $DIR/$tdir/$tfile ||
16186                 error "DoM file mismatch after migration"
16187 }
16188 run_test 230j "DoM file data not changed after dir migration"
16189
16190 test_230k() {
16191         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
16192         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16193                 skip "Need MDS version at least 2.11.56"
16194
16195         local total=20
16196         local files_on_starting_mdt=0
16197
16198         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
16199         $LFS getdirstripe $DIR/$tdir
16200         for i in $(seq $total); do
16201                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
16202                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16203                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16204         done
16205
16206         echo "$files_on_starting_mdt files on MDT0"
16207
16208         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
16209         $LFS getdirstripe $DIR/$tdir
16210
16211         files_on_starting_mdt=0
16212         for i in $(seq $total); do
16213                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16214                         error "file $tfile.$i mismatch after migration"
16215                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
16216                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16217         done
16218
16219         echo "$files_on_starting_mdt files on MDT1 after migration"
16220         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
16221
16222         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
16223         $LFS getdirstripe $DIR/$tdir
16224
16225         files_on_starting_mdt=0
16226         for i in $(seq $total); do
16227                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16228                         error "file $tfile.$i mismatch after 2nd migration"
16229                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16230                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16231         done
16232
16233         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
16234         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
16235
16236         true
16237 }
16238 run_test 230k "file data not changed after dir migration"
16239
16240 test_230l() {
16241         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16242         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16243                 skip "Need MDS version at least 2.11.56"
16244
16245         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
16246         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
16247                 error "create files under remote dir failed $i"
16248         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
16249 }
16250 run_test 230l "readdir between MDTs won't crash"
16251
16252 test_231a()
16253 {
16254         # For simplicity this test assumes that max_pages_per_rpc
16255         # is the same across all OSCs
16256         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
16257         local bulk_size=$((max_pages * PAGE_SIZE))
16258         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
16259                                        head -n 1)
16260
16261         mkdir -p $DIR/$tdir
16262         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
16263                 error "failed to set stripe with -S ${brw_size}M option"
16264
16265         # clear the OSC stats
16266         $LCTL set_param osc.*.stats=0 &>/dev/null
16267         stop_writeback
16268
16269         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
16270         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
16271                 oflag=direct &>/dev/null || error "dd failed"
16272
16273         sync; sleep 1; sync # just to be safe
16274         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
16275         if [ x$nrpcs != "x1" ]; then
16276                 $LCTL get_param osc.*.stats
16277                 error "found $nrpcs ost_write RPCs, not 1 as expected"
16278         fi
16279
16280         start_writeback
16281         # Drop the OSC cache, otherwise we will read from it
16282         cancel_lru_locks osc
16283
16284         # clear the OSC stats
16285         $LCTL set_param osc.*.stats=0 &>/dev/null
16286
16287         # Client reads $bulk_size.
16288         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
16289                 iflag=direct &>/dev/null || error "dd failed"
16290
16291         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
16292         if [ x$nrpcs != "x1" ]; then
16293                 $LCTL get_param osc.*.stats
16294                 error "found $nrpcs ost_read RPCs, not 1 as expected"
16295         fi
16296 }
16297 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
16298
16299 test_231b() {
16300         mkdir -p $DIR/$tdir
16301         local i
16302         for i in {0..1023}; do
16303                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
16304                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
16305                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
16306         done
16307         sync
16308 }
16309 run_test 231b "must not assert on fully utilized OST request buffer"
16310
16311 test_232a() {
16312         mkdir -p $DIR/$tdir
16313         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16314
16315         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16316         do_facet ost1 $LCTL set_param fail_loc=0x31c
16317
16318         # ignore dd failure
16319         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
16320
16321         do_facet ost1 $LCTL set_param fail_loc=0
16322         umount_client $MOUNT || error "umount failed"
16323         mount_client $MOUNT || error "mount failed"
16324         stop ost1 || error "cannot stop ost1"
16325         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16326 }
16327 run_test 232a "failed lock should not block umount"
16328
16329 test_232b() {
16330         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
16331                 skip "Need MDS version at least 2.10.58"
16332
16333         mkdir -p $DIR/$tdir
16334         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16335         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
16336         sync
16337         cancel_lru_locks osc
16338
16339         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16340         do_facet ost1 $LCTL set_param fail_loc=0x31c
16341
16342         # ignore failure
16343         $LFS data_version $DIR/$tdir/$tfile || true
16344
16345         do_facet ost1 $LCTL set_param fail_loc=0
16346         umount_client $MOUNT || error "umount failed"
16347         mount_client $MOUNT || error "mount failed"
16348         stop ost1 || error "cannot stop ost1"
16349         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16350 }
16351 run_test 232b "failed data version lock should not block umount"
16352
16353 test_233a() {
16354         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
16355                 skip "Need MDS version at least 2.3.64"
16356         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
16357
16358         local fid=$($LFS path2fid $MOUNT)
16359
16360         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16361                 error "cannot access $MOUNT using its FID '$fid'"
16362 }
16363 run_test 233a "checking that OBF of the FS root succeeds"
16364
16365 test_233b() {
16366         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
16367                 skip "Need MDS version at least 2.5.90"
16368         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
16369
16370         local fid=$($LFS path2fid $MOUNT/.lustre)
16371
16372         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16373                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
16374
16375         fid=$($LFS path2fid $MOUNT/.lustre/fid)
16376         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16377                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
16378 }
16379 run_test 233b "checking that OBF of the FS .lustre succeeds"
16380
16381 test_234() {
16382         local p="$TMP/sanityN-$TESTNAME.parameters"
16383         save_lustre_params client "llite.*.xattr_cache" > $p
16384         lctl set_param llite.*.xattr_cache 1 ||
16385                 skip_env "xattr cache is not supported"
16386
16387         mkdir -p $DIR/$tdir || error "mkdir failed"
16388         touch $DIR/$tdir/$tfile || error "touch failed"
16389         # OBD_FAIL_LLITE_XATTR_ENOMEM
16390         $LCTL set_param fail_loc=0x1405
16391         getfattr -n user.attr $DIR/$tdir/$tfile &&
16392                 error "getfattr should have failed with ENOMEM"
16393         $LCTL set_param fail_loc=0x0
16394         rm -rf $DIR/$tdir
16395
16396         restore_lustre_params < $p
16397         rm -f $p
16398 }
16399 run_test 234 "xattr cache should not crash on ENOMEM"
16400
16401 test_235() {
16402         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
16403                 skip "Need MDS version at least 2.4.52"
16404
16405         flock_deadlock $DIR/$tfile
16406         local RC=$?
16407         case $RC in
16408                 0)
16409                 ;;
16410                 124) error "process hangs on a deadlock"
16411                 ;;
16412                 *) error "error executing flock_deadlock $DIR/$tfile"
16413                 ;;
16414         esac
16415 }
16416 run_test 235 "LU-1715: flock deadlock detection does not work properly"
16417
16418 #LU-2935
16419 test_236() {
16420         check_swap_layouts_support
16421
16422         local ref1=/etc/passwd
16423         local ref2=/etc/group
16424         local file1=$DIR/$tdir/f1
16425         local file2=$DIR/$tdir/f2
16426
16427         test_mkdir -c1 $DIR/$tdir
16428         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
16429         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
16430         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
16431         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
16432         local fd=$(free_fd)
16433         local cmd="exec $fd<>$file2"
16434         eval $cmd
16435         rm $file2
16436         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
16437                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
16438         cmd="exec $fd>&-"
16439         eval $cmd
16440         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16441
16442         #cleanup
16443         rm -rf $DIR/$tdir
16444 }
16445 run_test 236 "Layout swap on open unlinked file"
16446
16447 # LU-4659 linkea consistency
16448 test_238() {
16449         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16450                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16451                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16452                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16453
16454         touch $DIR/$tfile
16455         ln $DIR/$tfile $DIR/$tfile.lnk
16456         touch $DIR/$tfile.new
16457         mv $DIR/$tfile.new $DIR/$tfile
16458         local fid1=$($LFS path2fid $DIR/$tfile)
16459         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
16460         local path1=$($LFS fid2path $FSNAME "$fid1")
16461         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
16462         local path2=$($LFS fid2path $FSNAME "$fid2")
16463         [ $tfile.lnk == $path2 ] ||
16464                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
16465         rm -f $DIR/$tfile*
16466 }
16467 run_test 238 "Verify linkea consistency"
16468
16469 test_239A() { # was test_239
16470         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
16471                 skip "Need MDS version at least 2.5.60"
16472
16473         local list=$(comma_list $(mdts_nodes))
16474
16475         mkdir -p $DIR/$tdir
16476         createmany -o $DIR/$tdir/f- 5000
16477         unlinkmany $DIR/$tdir/f- 5000
16478         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
16479                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
16480         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
16481                         osp.*MDT*.sync_in_flight" | calc_sum)
16482         [ "$changes" -eq 0 ] || error "$changes not synced"
16483 }
16484 run_test 239A "osp_sync test"
16485
16486 test_239a() { #LU-5297
16487         remote_mds_nodsh && skip "remote MDS with nodsh"
16488
16489         touch $DIR/$tfile
16490         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
16491         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
16492         chgrp $RUNAS_GID $DIR/$tfile
16493         wait_delete_completed
16494 }
16495 run_test 239a "process invalid osp sync record correctly"
16496
16497 test_239b() { #LU-5297
16498         remote_mds_nodsh && skip "remote MDS with nodsh"
16499
16500         touch $DIR/$tfile1
16501         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
16502         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
16503         chgrp $RUNAS_GID $DIR/$tfile1
16504         wait_delete_completed
16505         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16506         touch $DIR/$tfile2
16507         chgrp $RUNAS_GID $DIR/$tfile2
16508         wait_delete_completed
16509 }
16510 run_test 239b "process osp sync record with ENOMEM error correctly"
16511
16512 test_240() {
16513         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16514         remote_mds_nodsh && skip "remote MDS with nodsh"
16515
16516         mkdir -p $DIR/$tdir
16517
16518         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
16519                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
16520         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
16521                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
16522
16523         umount_client $MOUNT || error "umount failed"
16524         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
16525         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
16526         mount_client $MOUNT || error "failed to mount client"
16527
16528         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
16529         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
16530 }
16531 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
16532
16533 test_241_bio() {
16534         local count=$1
16535         local bsize=$2
16536
16537         for LOOP in $(seq $count); do
16538                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
16539                 cancel_lru_locks $OSC || true
16540         done
16541 }
16542
16543 test_241_dio() {
16544         local count=$1
16545         local bsize=$2
16546
16547         for LOOP in $(seq $1); do
16548                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
16549                         2>/dev/null
16550         done
16551 }
16552
16553 test_241a() { # was test_241
16554         local bsize=$PAGE_SIZE
16555
16556         (( bsize < 40960 )) && bsize=40960
16557         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16558         ls -la $DIR/$tfile
16559         cancel_lru_locks $OSC
16560         test_241_bio 1000 $bsize &
16561         PID=$!
16562         test_241_dio 1000 $bsize
16563         wait $PID
16564 }
16565 run_test 241a "bio vs dio"
16566
16567 test_241b() {
16568         local bsize=$PAGE_SIZE
16569
16570         (( bsize < 40960 )) && bsize=40960
16571         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16572         ls -la $DIR/$tfile
16573         test_241_dio 1000 $bsize &
16574         PID=$!
16575         test_241_dio 1000 $bsize
16576         wait $PID
16577 }
16578 run_test 241b "dio vs dio"
16579
16580 test_242() {
16581         remote_mds_nodsh && skip "remote MDS with nodsh"
16582
16583         mkdir -p $DIR/$tdir
16584         touch $DIR/$tdir/$tfile
16585
16586         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
16587         do_facet mds1 lctl set_param fail_loc=0x105
16588         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
16589
16590         do_facet mds1 lctl set_param fail_loc=0
16591         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
16592 }
16593 run_test 242 "mdt_readpage failure should not cause directory unreadable"
16594
16595 test_243()
16596 {
16597         test_mkdir $DIR/$tdir
16598         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
16599 }
16600 run_test 243 "various group lock tests"
16601
16602 test_244()
16603 {
16604         test_mkdir $DIR/$tdir
16605         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
16606         sendfile_grouplock $DIR/$tdir/$tfile || \
16607                 error "sendfile+grouplock failed"
16608         rm -rf $DIR/$tdir
16609 }
16610 run_test 244 "sendfile with group lock tests"
16611
16612 test_245() {
16613         local flagname="multi_mod_rpcs"
16614         local connect_data_name="max_mod_rpcs"
16615         local out
16616
16617         # check if multiple modify RPCs flag is set
16618         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
16619                 grep "connect_flags:")
16620         echo "$out"
16621
16622         echo "$out" | grep -qw $flagname
16623         if [ $? -ne 0 ]; then
16624                 echo "connect flag $flagname is not set"
16625                 return
16626         fi
16627
16628         # check if multiple modify RPCs data is set
16629         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
16630         echo "$out"
16631
16632         echo "$out" | grep -qw $connect_data_name ||
16633                 error "import should have connect data $connect_data_name"
16634 }
16635 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
16636
16637 test_246() { # LU-7371
16638         remote_ost_nodsh && skip "remote OST with nodsh"
16639         [ $OST1_VERSION -lt $(version_code 2.7.62) ] &&
16640                 skip "Need OST version >= 2.7.62"
16641
16642         do_facet ost1 $LCTL set_param fail_val=4095
16643 #define OBD_FAIL_OST_READ_SIZE          0x234
16644         do_facet ost1 $LCTL set_param fail_loc=0x234
16645         $LFS setstripe $DIR/$tfile -i 0 -c 1
16646         dd if=/dev/zero of=$DIR/$tfile bs=4095 count=1 > /dev/null 2>&1
16647         cancel_lru_locks $FSNAME-OST0000
16648         dd if=$DIR/$tfile of=/dev/null bs=1048576 || error "Read failed"
16649 }
16650 run_test 246 "Read file of size 4095 should return right length"
16651
16652 cleanup_247() {
16653         local submount=$1
16654
16655         trap 0
16656         umount_client $submount
16657         rmdir $submount
16658 }
16659
16660 test_247a() {
16661         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16662                 grep -q subtree ||
16663                 skip_env "Fileset feature is not supported"
16664
16665         local submount=${MOUNT}_$tdir
16666
16667         mkdir $MOUNT/$tdir
16668         mkdir -p $submount || error "mkdir $submount failed"
16669         FILESET="$FILESET/$tdir" mount_client $submount ||
16670                 error "mount $submount failed"
16671         trap "cleanup_247 $submount" EXIT
16672         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
16673         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
16674                 error "read $MOUNT/$tdir/$tfile failed"
16675         cleanup_247 $submount
16676 }
16677 run_test 247a "mount subdir as fileset"
16678
16679 test_247b() {
16680         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16681                 skip_env "Fileset feature is not supported"
16682
16683         local submount=${MOUNT}_$tdir
16684
16685         rm -rf $MOUNT/$tdir
16686         mkdir -p $submount || error "mkdir $submount failed"
16687         SKIP_FILESET=1
16688         FILESET="$FILESET/$tdir" mount_client $submount &&
16689                 error "mount $submount should fail"
16690         rmdir $submount
16691 }
16692 run_test 247b "mount subdir that dose not exist"
16693
16694 test_247c() {
16695         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16696                 skip_env "Fileset feature is not supported"
16697
16698         local submount=${MOUNT}_$tdir
16699
16700         mkdir -p $MOUNT/$tdir/dir1
16701         mkdir -p $submount || error "mkdir $submount failed"
16702         trap "cleanup_247 $submount" EXIT
16703         FILESET="$FILESET/$tdir" mount_client $submount ||
16704                 error "mount $submount failed"
16705         local fid=$($LFS path2fid $MOUNT/)
16706         $LFS fid2path $submount $fid && error "fid2path should fail"
16707         cleanup_247 $submount
16708 }
16709 run_test 247c "running fid2path outside root"
16710
16711 test_247d() {
16712         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16713                 skip "Fileset feature is not supported"
16714
16715         local submount=${MOUNT}_$tdir
16716
16717         mkdir -p $MOUNT/$tdir/dir1
16718         mkdir -p $submount || error "mkdir $submount failed"
16719         FILESET="$FILESET/$tdir" mount_client $submount ||
16720                 error "mount $submount failed"
16721         trap "cleanup_247 $submount" EXIT
16722         local fid=$($LFS path2fid $submount/dir1)
16723         $LFS fid2path $submount $fid || error "fid2path should succeed"
16724         cleanup_247 $submount
16725 }
16726 run_test 247d "running fid2path inside root"
16727
16728 # LU-8037
16729 test_247e() {
16730         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16731                 grep -q subtree ||
16732                 skip "Fileset feature is not supported"
16733
16734         local submount=${MOUNT}_$tdir
16735
16736         mkdir $MOUNT/$tdir
16737         mkdir -p $submount || error "mkdir $submount failed"
16738         FILESET="$FILESET/.." mount_client $submount &&
16739                 error "mount $submount should fail"
16740         rmdir $submount
16741 }
16742 run_test 247e "mount .. as fileset"
16743
16744 test_248() {
16745         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
16746         [ -z "$fast_read_sav" ] && skip "no fast read support"
16747
16748         # create a large file for fast read verification
16749         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
16750
16751         # make sure the file is created correctly
16752         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
16753                 { rm -f $DIR/$tfile; skip "file creation error"; }
16754
16755         echo "Test 1: verify that fast read is 4 times faster on cache read"
16756
16757         # small read with fast read enabled
16758         $LCTL set_param -n llite.*.fast_read=1
16759         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16760                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16761                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16762         # small read with fast read disabled
16763         $LCTL set_param -n llite.*.fast_read=0
16764         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16765                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16766                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16767
16768         # verify that fast read is 4 times faster for cache read
16769         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
16770                 error_not_in_vm "fast read was not 4 times faster: " \
16771                            "$t_fast vs $t_slow"
16772
16773         echo "Test 2: verify the performance between big and small read"
16774         $LCTL set_param -n llite.*.fast_read=1
16775
16776         # 1k non-cache read
16777         cancel_lru_locks osc
16778         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16779                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16780                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16781
16782         # 1M non-cache read
16783         cancel_lru_locks osc
16784         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16785                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16786                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16787
16788         # verify that big IO is not 4 times faster than small IO
16789         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
16790                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
16791
16792         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
16793         rm -f $DIR/$tfile
16794 }
16795 run_test 248 "fast read verification"
16796
16797 test_249() { # LU-7890
16798         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
16799                 skip "Need at least version 2.8.54"
16800
16801         rm -f $DIR/$tfile
16802         $LFS setstripe -c 1 $DIR/$tfile
16803         # Offset 2T == 4k * 512M
16804         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
16805                 error "dd to 2T offset failed"
16806 }
16807 run_test 249 "Write above 2T file size"
16808
16809 test_250() {
16810         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
16811          && skip "no 16TB file size limit on ZFS"
16812
16813         $LFS setstripe -c 1 $DIR/$tfile
16814         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
16815         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
16816         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
16817         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
16818                 conv=notrunc,fsync && error "append succeeded"
16819         return 0
16820 }
16821 run_test 250 "Write above 16T limit"
16822
16823 test_251() {
16824         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
16825
16826         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
16827         #Skip once - writing the first stripe will succeed
16828         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16829         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
16830                 error "short write happened"
16831
16832         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16833         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
16834                 error "short read happened"
16835
16836         rm -f $DIR/$tfile
16837 }
16838 run_test 251 "Handling short read and write correctly"
16839
16840 test_252() {
16841         remote_mds_nodsh && skip "remote MDS with nodsh"
16842         remote_ost_nodsh && skip "remote OST with nodsh"
16843         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
16844                 skip_env "ldiskfs only test"
16845         fi
16846
16847         local tgt
16848         local dev
16849         local out
16850         local uuid
16851         local num
16852         local gen
16853
16854         # check lr_reader on OST0000
16855         tgt=ost1
16856         dev=$(facet_device $tgt)
16857         out=$(do_facet $tgt $LR_READER $dev)
16858         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16859         echo "$out"
16860         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
16861         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
16862                 error "Invalid uuid returned by $LR_READER on target $tgt"
16863         echo -e "uuid returned by $LR_READER is '$uuid'\n"
16864
16865         # check lr_reader -c on MDT0000
16866         tgt=mds1
16867         dev=$(facet_device $tgt)
16868         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
16869                 skip "$LR_READER does not support additional options"
16870         fi
16871         out=$(do_facet $tgt $LR_READER -c $dev)
16872         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16873         echo "$out"
16874         num=$(echo "$out" | grep -c "mdtlov")
16875         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
16876                 error "Invalid number of mdtlov clients returned by $LR_READER"
16877         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
16878
16879         # check lr_reader -cr on MDT0000
16880         out=$(do_facet $tgt $LR_READER -cr $dev)
16881         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16882         echo "$out"
16883         echo "$out" | grep -q "^reply_data:$" ||
16884                 error "$LR_READER should have returned 'reply_data' section"
16885         num=$(echo "$out" | grep -c "client_generation")
16886         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
16887 }
16888 run_test 252 "check lr_reader tool"
16889
16890 test_253_fill_ost() {
16891         local size_mb #how many MB should we write to pass watermark
16892         local lwm=$3  #low watermark
16893         local free_10mb #10% of free space
16894
16895         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16896         size_mb=$((free_kb / 1024 - lwm))
16897         free_10mb=$((free_kb / 10240))
16898         #If 10% of free space cross low watermark use it
16899         if (( free_10mb > size_mb )); then
16900                 size_mb=$free_10mb
16901         else
16902                 #At least we need to store 1.1 of difference between
16903                 #free space and low watermark
16904                 size_mb=$((size_mb + size_mb / 10))
16905         fi
16906         if (( lwm <= $((free_kb / 1024)) )) || [ ! -f $DIR/$tdir/1 ]; then
16907                 dd if=/dev/zero of=$DIR/$tdir/1 bs=1M count=$size_mb \
16908                          oflag=append conv=notrunc
16909         fi
16910
16911         sleep_maxage
16912
16913         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16914         echo "OST still has $((free_kb / 1024)) mbytes free"
16915 }
16916
16917 test_253() {
16918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16919         remote_mds_nodsh && skip "remote MDS with nodsh"
16920         remote_mgs_nodsh && skip "remote MGS with nodsh"
16921
16922         local ostidx=0
16923         local rc=0
16924
16925         local ost_name=$($LFS osts |
16926                 sed -n 's/^'$ostidx': \(.*\)_UUID .*/\1/p')
16927         # on the mdt's osc
16928         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
16929         do_facet $SINGLEMDS $LCTL get_param -n \
16930                 osp.$mdtosc_proc1.reserved_mb_high ||
16931                 skip  "remote MDS does not support reserved_mb_high"
16932
16933         rm -rf $DIR/$tdir
16934         wait_mds_ost_sync
16935         wait_delete_completed
16936         mkdir $DIR/$tdir
16937
16938         local last_wm_h=$(do_facet $SINGLEMDS $LCTL get_param -n \
16939                         osp.$mdtosc_proc1.reserved_mb_high)
16940         local last_wm_l=$(do_facet $SINGLEMDS $LCTL get_param -n \
16941                         osp.$mdtosc_proc1.reserved_mb_low)
16942         echo "prev high watermark $last_wm_h, prev low watermark $last_wm_l"
16943
16944         if ! combined_mgs_mds ; then
16945                 mount_mgs_client
16946         fi
16947         create_pool $FSNAME.$TESTNAME || error "Pool creation failed"
16948         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $ost_name ||
16949                 error "Adding $ost_name to pool failed"
16950
16951         # Wait for client to see a OST at pool
16952         wait_update $HOSTNAME "$LCTL get_param -n
16953                 lov.$FSNAME-*.pools.$TESTNAME | sort -u |
16954                 grep $ost_name" "$ost_name""_UUID" $((TIMEOUT/2)) ||
16955                 error "Client can not see the pool"
16956         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
16957                 error "Setstripe failed"
16958
16959         dd if=/dev/zero of=$DIR/$tdir/0 bs=1M count=10
16960         local blocks=$($LFS df $MOUNT | grep $ost_name | awk '{ print $4 }')
16961         echo "OST still has $((blocks/1024)) mbytes free"
16962
16963         local new_lwm=$((blocks/1024-10))
16964         do_facet $SINGLEMDS $LCTL set_param \
16965                         osp.$mdtosc_proc1.reserved_mb_high=$((new_lwm+5))
16966         do_facet $SINGLEMDS $LCTL set_param \
16967                         osp.$mdtosc_proc1.reserved_mb_low=$new_lwm
16968
16969         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16970
16971         #First enospc could execute orphan deletion so repeat.
16972         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16973
16974         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16975                         osp.$mdtosc_proc1.prealloc_status)
16976         echo "prealloc_status $oa_status"
16977
16978         dd if=/dev/zero of=$DIR/$tdir/2 bs=1M count=1 &&
16979                 error "File creation should fail"
16980         #object allocation was stopped, but we still able to append files
16981         dd if=/dev/zero of=$DIR/$tdir/1 bs=1M seek=6 count=5 oflag=append ||
16982                 error "Append failed"
16983         rm -f $DIR/$tdir/1 $DIR/$tdir/0 $DIR/$tdir/r*
16984
16985         wait_delete_completed
16986
16987         sleep_maxage
16988
16989         for i in $(seq 10 12); do
16990                 dd if=/dev/zero of=$DIR/$tdir/$i bs=1M count=1 2>/dev/null ||
16991                         error "File creation failed after rm";
16992         done
16993
16994         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16995                         osp.$mdtosc_proc1.prealloc_status)
16996         echo "prealloc_status $oa_status"
16997
16998         if (( oa_status != 0 )); then
16999                 error "Object allocation still disable after rm"
17000         fi
17001         do_facet $SINGLEMDS $LCTL set_param \
17002                         osp.$mdtosc_proc1.reserved_mb_high=$last_wm_h
17003         do_facet $SINGLEMDS $LCTL set_param \
17004                         osp.$mdtosc_proc1.reserved_mb_low=$last_wm_l
17005
17006
17007         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $ost_name ||
17008                 error "Remove $ost_name from pool failed"
17009         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17010                 error "Pool destroy fialed"
17011
17012         if ! combined_mgs_mds ; then
17013                 umount_mgs_client
17014         fi
17015 }
17016 run_test 253 "Check object allocation limit"
17017
17018 test_254() {
17019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17020         remote_mds_nodsh && skip "remote MDS with nodsh"
17021         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
17022                 skip "MDS does not support changelog_size"
17023
17024         local cl_user
17025         local MDT0=$(facet_svc $SINGLEMDS)
17026
17027         changelog_register || error "changelog_register failed"
17028
17029         changelog_clear 0 || error "changelog_clear failed"
17030
17031         local size1=$(do_facet $SINGLEMDS \
17032                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17033         echo "Changelog size $size1"
17034
17035         rm -rf $DIR/$tdir
17036         $LFS mkdir -i 0 $DIR/$tdir
17037         # change something
17038         mkdir -p $DIR/$tdir/pics/2008/zachy
17039         touch $DIR/$tdir/pics/2008/zachy/timestamp
17040         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
17041         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17042         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17043         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17044         rm $DIR/$tdir/pics/desktop.jpg
17045
17046         local size2=$(do_facet $SINGLEMDS \
17047                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17048         echo "Changelog size after work $size2"
17049
17050         (( $size2 > $size1 )) ||
17051                 error "new Changelog size=$size2 less than old size=$size1"
17052 }
17053 run_test 254 "Check changelog size"
17054
17055 ladvise_no_type()
17056 {
17057         local type=$1
17058         local file=$2
17059
17060         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
17061                 awk -F: '{print $2}' | grep $type > /dev/null
17062         if [ $? -ne 0 ]; then
17063                 return 0
17064         fi
17065         return 1
17066 }
17067
17068 ladvise_no_ioctl()
17069 {
17070         local file=$1
17071
17072         lfs ladvise -a willread $file > /dev/null 2>&1
17073         if [ $? -eq 0 ]; then
17074                 return 1
17075         fi
17076
17077         lfs ladvise -a willread $file 2>&1 |
17078                 grep "Inappropriate ioctl for device" > /dev/null
17079         if [ $? -eq 0 ]; then
17080                 return 0
17081         fi
17082         return 1
17083 }
17084
17085 percent() {
17086         bc <<<"scale=2; ($1 - $2) * 100 / $2"
17087 }
17088
17089 # run a random read IO workload
17090 # usage: random_read_iops <filename> <filesize> <iosize>
17091 random_read_iops() {
17092         local file=$1
17093         local fsize=$2
17094         local iosize=${3:-4096}
17095
17096         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
17097                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
17098 }
17099
17100 drop_file_oss_cache() {
17101         local file="$1"
17102         local nodes="$2"
17103
17104         $LFS ladvise -a dontneed $file 2>/dev/null ||
17105                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
17106 }
17107
17108 ladvise_willread_performance()
17109 {
17110         local repeat=10
17111         local average_origin=0
17112         local average_cache=0
17113         local average_ladvise=0
17114
17115         for ((i = 1; i <= $repeat; i++)); do
17116                 echo "Iter $i/$repeat: reading without willread hint"
17117                 cancel_lru_locks osc
17118                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17119                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
17120                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
17121                 average_origin=$(bc <<<"$average_origin + $speed_origin")
17122
17123                 cancel_lru_locks osc
17124                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
17125                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
17126                 average_cache=$(bc <<<"$average_cache + $speed_cache")
17127
17128                 cancel_lru_locks osc
17129                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17130                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
17131                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
17132                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
17133                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
17134         done
17135         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
17136         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
17137         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
17138
17139         speedup_cache=$(percent $average_cache $average_origin)
17140         speedup_ladvise=$(percent $average_ladvise $average_origin)
17141
17142         echo "Average uncached read: $average_origin"
17143         echo "Average speedup with OSS cached read: " \
17144                 "$average_cache = +$speedup_cache%"
17145         echo "Average speedup with ladvise willread: " \
17146                 "$average_ladvise = +$speedup_ladvise%"
17147
17148         local lowest_speedup=20
17149         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
17150                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
17151                         "got $average_cache%. Skipping ladvise willread check."
17152                 return 0
17153         fi
17154
17155         # the test won't work on ZFS until it supports 'ladvise dontneed', but
17156         # it is still good to run until then to exercise 'ladvise willread'
17157         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17158                 [ "$ost1_FSTYPE" = "zfs" ] &&
17159                 echo "osd-zfs does not support dontneed or drop_caches" &&
17160                 return 0
17161
17162         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
17163         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
17164                 error_not_in_vm "Speedup with willread is less than " \
17165                         "$lowest_speedup%, got $average_ladvise%"
17166 }
17167
17168 test_255a() {
17169         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17170                 skip "lustre < 2.8.54 does not support ladvise "
17171         remote_ost_nodsh && skip "remote OST with nodsh"
17172
17173         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
17174
17175         ladvise_no_type willread $DIR/$tfile &&
17176                 skip "willread ladvise is not supported"
17177
17178         ladvise_no_ioctl $DIR/$tfile &&
17179                 skip "ladvise ioctl is not supported"
17180
17181         local size_mb=100
17182         local size=$((size_mb * 1048576))
17183         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17184                 error "dd to $DIR/$tfile failed"
17185
17186         lfs ladvise -a willread $DIR/$tfile ||
17187                 error "Ladvise failed with no range argument"
17188
17189         lfs ladvise -a willread -s 0 $DIR/$tfile ||
17190                 error "Ladvise failed with no -l or -e argument"
17191
17192         lfs ladvise -a willread -e 1 $DIR/$tfile ||
17193                 error "Ladvise failed with only -e argument"
17194
17195         lfs ladvise -a willread -l 1 $DIR/$tfile ||
17196                 error "Ladvise failed with only -l argument"
17197
17198         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
17199                 error "End offset should not be smaller than start offset"
17200
17201         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
17202                 error "End offset should not be equal to start offset"
17203
17204         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
17205                 error "Ladvise failed with overflowing -s argument"
17206
17207         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
17208                 error "Ladvise failed with overflowing -e argument"
17209
17210         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
17211                 error "Ladvise failed with overflowing -l argument"
17212
17213         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
17214                 error "Ladvise succeeded with conflicting -l and -e arguments"
17215
17216         echo "Synchronous ladvise should wait"
17217         local delay=4
17218 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
17219         do_nodes $(comma_list $(osts_nodes)) \
17220                 $LCTL set_param fail_val=$delay fail_loc=0x237
17221
17222         local start_ts=$SECONDS
17223         lfs ladvise -a willread $DIR/$tfile ||
17224                 error "Ladvise failed with no range argument"
17225         local end_ts=$SECONDS
17226         local inteval_ts=$((end_ts - start_ts))
17227
17228         if [ $inteval_ts -lt $(($delay - 1)) ]; then
17229                 error "Synchronous advice didn't wait reply"
17230         fi
17231
17232         echo "Asynchronous ladvise shouldn't wait"
17233         local start_ts=$SECONDS
17234         lfs ladvise -a willread -b $DIR/$tfile ||
17235                 error "Ladvise failed with no range argument"
17236         local end_ts=$SECONDS
17237         local inteval_ts=$((end_ts - start_ts))
17238
17239         if [ $inteval_ts -gt $(($delay / 2)) ]; then
17240                 error "Asynchronous advice blocked"
17241         fi
17242
17243         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
17244         ladvise_willread_performance
17245 }
17246 run_test 255a "check 'lfs ladvise -a willread'"
17247
17248 facet_meminfo() {
17249         local facet=$1
17250         local info=$2
17251
17252         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
17253 }
17254
17255 test_255b() {
17256         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17257                 skip "lustre < 2.8.54 does not support ladvise "
17258         remote_ost_nodsh && skip "remote OST with nodsh"
17259
17260         lfs setstripe -c 1 -i 0 $DIR/$tfile
17261
17262         ladvise_no_type dontneed $DIR/$tfile &&
17263                 skip "dontneed ladvise is not supported"
17264
17265         ladvise_no_ioctl $DIR/$tfile &&
17266                 skip "ladvise ioctl is not supported"
17267
17268         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17269                 [ "$ost1_FSTYPE" = "zfs" ] &&
17270                 skip "zfs-osd does not support 'ladvise dontneed'"
17271
17272         local size_mb=100
17273         local size=$((size_mb * 1048576))
17274         # In order to prevent disturbance of other processes, only check 3/4
17275         # of the memory usage
17276         local kibibytes=$((size_mb * 1024 * 3 / 4))
17277
17278         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17279                 error "dd to $DIR/$tfile failed"
17280
17281         #force write to complete before dropping OST cache & checking memory
17282         sync
17283
17284         local total=$(facet_meminfo ost1 MemTotal)
17285         echo "Total memory: $total KiB"
17286
17287         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
17288         local before_read=$(facet_meminfo ost1 Cached)
17289         echo "Cache used before read: $before_read KiB"
17290
17291         lfs ladvise -a willread $DIR/$tfile ||
17292                 error "Ladvise willread failed"
17293         local after_read=$(facet_meminfo ost1 Cached)
17294         echo "Cache used after read: $after_read KiB"
17295
17296         lfs ladvise -a dontneed $DIR/$tfile ||
17297                 error "Ladvise dontneed again failed"
17298         local no_read=$(facet_meminfo ost1 Cached)
17299         echo "Cache used after dontneed ladvise: $no_read KiB"
17300
17301         if [ $total -lt $((before_read + kibibytes)) ]; then
17302                 echo "Memory is too small, abort checking"
17303                 return 0
17304         fi
17305
17306         if [ $((before_read + kibibytes)) -gt $after_read ]; then
17307                 error "Ladvise willread should use more memory" \
17308                         "than $kibibytes KiB"
17309         fi
17310
17311         if [ $((no_read + kibibytes)) -gt $after_read ]; then
17312                 error "Ladvise dontneed should release more memory" \
17313                         "than $kibibytes KiB"
17314         fi
17315 }
17316 run_test 255b "check 'lfs ladvise -a dontneed'"
17317
17318 test_255c() {
17319         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
17320                 skip "lustre < 2.10.53 does not support lockahead"
17321
17322         local count
17323         local new_count
17324         local difference
17325         local i
17326         local rc
17327
17328         test_mkdir -p $DIR/$tdir
17329         $LFS setstripe -i 0 -c 1 $DIR/$tdir
17330
17331         #test 10 returns only success/failure
17332         i=10
17333         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17334         rc=$?
17335         if [ $rc -eq 255 ]; then
17336                 error "Ladvise test${i} failed, ${rc}"
17337         fi
17338
17339         #test 11 counts lock enqueue requests, all others count new locks
17340         i=11
17341         count=$(do_facet ost1 \
17342                 $LCTL get_param -n ost.OSS.ost.stats)
17343         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
17344
17345         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17346         rc=$?
17347         if [ $rc -eq 255 ]; then
17348                 error "Ladvise test${i} failed, ${rc}"
17349         fi
17350
17351         new_count=$(do_facet ost1 \
17352                 $LCTL get_param -n ost.OSS.ost.stats)
17353         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
17354                    awk '{ print $2 }')
17355
17356         difference="$((new_count - count))"
17357         if [ $difference -ne $rc ]; then
17358                 error "Ladvise test${i}, bad enqueue count, returned " \
17359                       "${rc}, actual ${difference}"
17360         fi
17361
17362         for i in $(seq 12 21); do
17363                 # If we do not do this, we run the risk of having too many
17364                 # locks and starting lock cancellation while we are checking
17365                 # lock counts.
17366                 cancel_lru_locks osc
17367
17368                 count=$($LCTL get_param -n \
17369                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17370
17371                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
17372                 rc=$?
17373                 if [ $rc -eq 255 ]; then
17374                         error "Ladvise test ${i} failed, ${rc}"
17375                 fi
17376
17377                 new_count=$($LCTL get_param -n \
17378                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17379                 difference="$((new_count - count))"
17380
17381                 # Test 15 output is divided by 100 to map down to valid return
17382                 if [ $i -eq 15 ]; then
17383                         rc="$((rc * 100))"
17384                 fi
17385
17386                 if [ $difference -ne $rc ]; then
17387                         error "Ladvise test ${i}, bad lock count, returned " \
17388                               "${rc}, actual ${difference}"
17389                 fi
17390         done
17391
17392         #test 22 returns only success/failure
17393         i=22
17394         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17395         rc=$?
17396         if [ $rc -eq 255 ]; then
17397                 error "Ladvise test${i} failed, ${rc}"
17398         fi
17399 }
17400 run_test 255c "suite of ladvise lockahead tests"
17401
17402 test_256() {
17403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17404         remote_mds_nodsh && skip "remote MDS with nodsh"
17405         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17406         changelog_users $SINGLEMDS | grep "^cl" &&
17407                 skip "active changelog user"
17408
17409         local cl_user
17410         local cat_sl
17411         local mdt_dev
17412
17413         mdt_dev=$(mdsdevname 1)
17414         echo $mdt_dev
17415
17416         changelog_register || error "changelog_register failed"
17417
17418         rm -rf $DIR/$tdir
17419         mkdir -p $DIR/$tdir
17420
17421         changelog_clear 0 || error "changelog_clear failed"
17422
17423         # change something
17424         touch $DIR/$tdir/{1..10}
17425
17426         # stop the MDT
17427         stop $SINGLEMDS || error "Fail to stop MDT"
17428
17429         # remount the MDT
17430
17431         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
17432
17433         #after mount new plainllog is used
17434         touch $DIR/$tdir/{11..19}
17435         local tmpfile=$(mktemp -u $tfile.XXXXXX)
17436         cat_sl=$(do_facet $SINGLEMDS "sync; \
17437                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
17438                  llog_reader $tmpfile | grep -c type=1064553b")
17439         do_facet $SINGLEMDS llog_reader $tmpfile
17440
17441         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
17442
17443         changelog_clear 0 || error "changelog_clear failed"
17444
17445         cat_sl=$(do_facet $SINGLEMDS "sync; \
17446                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
17447                  llog_reader $tmpfile | grep -c type=1064553b; rm -f $tmpfile")
17448
17449         if (( cat_sl == 2 )); then
17450                 error "Empty plain llog was not deleted from changelog catalog"
17451         elif (( cat_sl != 1 )); then
17452                 error "Active plain llog shouldn't be deleted from catalog"
17453         fi
17454 }
17455 run_test 256 "Check llog delete for empty and not full state"
17456
17457 test_257() {
17458         remote_mds_nodsh && skip "remote MDS with nodsh"
17459         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
17460                 skip "Need MDS version at least 2.8.55"
17461
17462         test_mkdir $DIR/$tdir
17463
17464         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
17465                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
17466         stat $DIR/$tdir
17467
17468 #define OBD_FAIL_MDS_XATTR_REP                  0x161
17469         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17470         local facet=mds$((mdtidx + 1))
17471         set_nodes_failloc $(facet_active_host $facet) 0x80000161
17472         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
17473
17474         stop $facet || error "stop MDS failed"
17475         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
17476                 error "start MDS fail"
17477         wait_recovery_complete $facet
17478 }
17479 run_test 257 "xattr locks are not lost"
17480
17481 # Verify we take the i_mutex when security requires it
17482 test_258a() {
17483 #define OBD_FAIL_IMUTEX_SEC 0x141c
17484         $LCTL set_param fail_loc=0x141c
17485         touch $DIR/$tfile
17486         chmod u+s $DIR/$tfile
17487         chmod a+rwx $DIR/$tfile
17488         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17489         RC=$?
17490         if [ $RC -ne 0 ]; then
17491                 error "error, failed to take i_mutex, rc=$?"
17492         fi
17493         rm -f $DIR/$tfile
17494 }
17495 run_test 258a "verify i_mutex security behavior when suid attributes is set"
17496
17497 # Verify we do NOT take the i_mutex in the normal case
17498 test_258b() {
17499 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
17500         $LCTL set_param fail_loc=0x141d
17501         touch $DIR/$tfile
17502         chmod a+rwx $DIR
17503         chmod a+rw $DIR/$tfile
17504         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17505         RC=$?
17506         if [ $RC -ne 0 ]; then
17507                 error "error, took i_mutex unnecessarily, rc=$?"
17508         fi
17509         rm -f $DIR/$tfile
17510
17511 }
17512 run_test 258b "verify i_mutex security behavior"
17513
17514 test_259() {
17515         local file=$DIR/$tfile
17516         local before
17517         local after
17518
17519         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17520
17521         stack_trap "rm -f $file" EXIT
17522
17523         wait_delete_completed
17524         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17525         echo "before: $before"
17526
17527         $LFS setstripe -i 0 -c 1 $file
17528         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
17529         sync_all_data
17530         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17531         echo "after write: $after"
17532
17533 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
17534         do_facet ost1 $LCTL set_param fail_loc=0x2301
17535         $TRUNCATE $file 0
17536         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17537         echo "after truncate: $after"
17538
17539         stop ost1
17540         do_facet ost1 $LCTL set_param fail_loc=0
17541         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17542         sleep 2
17543         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17544         echo "after restart: $after"
17545         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
17546                 error "missing truncate?"
17547
17548         return 0
17549 }
17550 run_test 259 "crash at delayed truncate"
17551
17552 test_260() {
17553 #define OBD_FAIL_MDC_CLOSE               0x806
17554         $LCTL set_param fail_loc=0x80000806
17555         touch $DIR/$tfile
17556
17557 }
17558 run_test 260 "Check mdc_close fail"
17559
17560 ### Data-on-MDT sanity tests ###
17561 test_270a() {
17562         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17563                 skip "Need MDS version at least 2.10.55 for DoM"
17564
17565         # create DoM file
17566         local dom=$DIR/$tdir/dom_file
17567         local tmp=$DIR/$tdir/tmp_file
17568
17569         mkdir -p $DIR/$tdir
17570
17571         # basic checks for DoM component creation
17572         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
17573                 error "Can set MDT layout to non-first entry"
17574
17575         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
17576                 error "Can define multiple entries as MDT layout"
17577
17578         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
17579
17580         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
17581         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
17582         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
17583
17584         local mdtidx=$($LFS getstripe -m $dom)
17585         local mdtname=MDT$(printf %04x $mdtidx)
17586         local facet=mds$((mdtidx + 1))
17587         local space_check=1
17588
17589         # Skip free space checks with ZFS
17590         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
17591
17592         # write
17593         sync
17594         local size_tmp=$((65536 * 3))
17595         local mdtfree1=$(do_facet $facet \
17596                          lctl get_param -n osd*.*$mdtname.kbytesfree)
17597
17598         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17599         # check also direct IO along write
17600         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
17601         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17602         sync
17603         cmp $tmp $dom || error "file data is different"
17604         [ $(stat -c%s $dom) == $size_tmp ] ||
17605                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17606         if [ $space_check == 1 ]; then
17607                 local mdtfree2=$(do_facet $facet \
17608                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
17609
17610                 # increase in usage from by $size_tmp
17611                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17612                         error "MDT free space wrong after write: " \
17613                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17614         fi
17615
17616         # truncate
17617         local size_dom=10000
17618
17619         $TRUNCATE $dom $size_dom
17620         [ $(stat -c%s $dom) == $size_dom ] ||
17621                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
17622         if [ $space_check == 1 ]; then
17623                 mdtfree1=$(do_facet $facet \
17624                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17625                 # decrease in usage from $size_tmp to new $size_dom
17626                 [ $(($mdtfree1 - $mdtfree2)) -ge \
17627                   $(((size_tmp - size_dom) / 1024)) ] ||
17628                         error "MDT free space is wrong after truncate: " \
17629                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
17630         fi
17631
17632         # append
17633         cat $tmp >> $dom
17634         sync
17635         size_dom=$((size_dom + size_tmp))
17636         [ $(stat -c%s $dom) == $size_dom ] ||
17637                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
17638         if [ $space_check == 1 ]; then
17639                 mdtfree2=$(do_facet $facet \
17640                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17641                 # increase in usage by $size_tmp from previous
17642                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17643                         error "MDT free space is wrong after append: " \
17644                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17645         fi
17646
17647         # delete
17648         rm $dom
17649         if [ $space_check == 1 ]; then
17650                 mdtfree1=$(do_facet $facet \
17651                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17652                 # decrease in usage by $size_dom from previous
17653                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
17654                         error "MDT free space is wrong after removal: " \
17655                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
17656         fi
17657
17658         # combined striping
17659         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
17660                 error "Can't create DoM + OST striping"
17661
17662         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
17663         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17664         # check also direct IO along write
17665         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17666         sync
17667         cmp $tmp $dom || error "file data is different"
17668         [ $(stat -c%s $dom) == $size_tmp ] ||
17669                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17670         rm $dom $tmp
17671
17672         return 0
17673 }
17674 run_test 270a "DoM: basic functionality tests"
17675
17676 test_270b() {
17677         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17678                 skip "Need MDS version at least 2.10.55"
17679
17680         local dom=$DIR/$tdir/dom_file
17681         local max_size=1048576
17682
17683         mkdir -p $DIR/$tdir
17684         $LFS setstripe -E $max_size -L mdt $dom
17685
17686         # truncate over the limit
17687         $TRUNCATE $dom $(($max_size + 1)) &&
17688                 error "successful truncate over the maximum size"
17689         # write over the limit
17690         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
17691                 error "successful write over the maximum size"
17692         # append over the limit
17693         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
17694         echo "12345" >> $dom && error "successful append over the maximum size"
17695         rm $dom
17696
17697         return 0
17698 }
17699 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
17700
17701 test_270c() {
17702         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17703                 skip "Need MDS version at least 2.10.55"
17704
17705         mkdir -p $DIR/$tdir
17706         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17707
17708         # check files inherit DoM EA
17709         touch $DIR/$tdir/first
17710         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
17711                 error "bad pattern"
17712         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
17713                 error "bad stripe count"
17714         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
17715                 error "bad stripe size"
17716
17717         # check directory inherits DoM EA and uses it as default
17718         mkdir $DIR/$tdir/subdir
17719         touch $DIR/$tdir/subdir/second
17720         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
17721                 error "bad pattern in sub-directory"
17722         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
17723                 error "bad stripe count in sub-directory"
17724         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
17725                 error "bad stripe size in sub-directory"
17726         return 0
17727 }
17728 run_test 270c "DoM: DoM EA inheritance tests"
17729
17730 test_270d() {
17731         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17732                 skip "Need MDS version at least 2.10.55"
17733
17734         mkdir -p $DIR/$tdir
17735         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17736
17737         # inherit default DoM striping
17738         mkdir $DIR/$tdir/subdir
17739         touch $DIR/$tdir/subdir/f1
17740
17741         # change default directory striping
17742         $LFS setstripe -c 1 $DIR/$tdir/subdir
17743         touch $DIR/$tdir/subdir/f2
17744         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
17745                 error "wrong default striping in file 2"
17746         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
17747                 error "bad pattern in file 2"
17748         return 0
17749 }
17750 run_test 270d "DoM: change striping from DoM to RAID0"
17751
17752 test_270e() {
17753         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17754                 skip "Need MDS version at least 2.10.55"
17755
17756         mkdir -p $DIR/$tdir/dom
17757         mkdir -p $DIR/$tdir/norm
17758         DOMFILES=20
17759         NORMFILES=10
17760         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
17761         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
17762
17763         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
17764         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
17765
17766         # find DoM files by layout
17767         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
17768         [ $NUM -eq  $DOMFILES ] ||
17769                 error "lfs find -L: found $NUM, expected $DOMFILES"
17770         echo "Test 1: lfs find 20 DOM files by layout: OK"
17771
17772         # there should be 1 dir with default DOM striping
17773         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
17774         [ $NUM -eq  1 ] ||
17775                 error "lfs find -L: found $NUM, expected 1 dir"
17776         echo "Test 2: lfs find 1 DOM dir by layout: OK"
17777
17778         # find DoM files by stripe size
17779         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
17780         [ $NUM -eq  $DOMFILES ] ||
17781                 error "lfs find -S: found $NUM, expected $DOMFILES"
17782         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
17783
17784         # find files by stripe offset except DoM files
17785         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
17786         [ $NUM -eq  $NORMFILES ] ||
17787                 error "lfs find -i: found $NUM, expected $NORMFILES"
17788         echo "Test 5: lfs find no DOM files by stripe index: OK"
17789         return 0
17790 }
17791 run_test 270e "DoM: lfs find with DoM files test"
17792
17793 test_270f() {
17794         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17795                 skip "Need MDS version at least 2.10.55"
17796
17797         local mdtname=${FSNAME}-MDT0000-mdtlov
17798         local dom=$DIR/$tdir/dom_file
17799         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
17800                                                 lod.$mdtname.dom_stripesize)
17801         local dom_limit=131072
17802
17803         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
17804         local dom_current=$(do_facet mds1 $LCTL get_param -n \
17805                                                 lod.$mdtname.dom_stripesize)
17806         [ ${dom_limit} -eq ${dom_current} ] ||
17807                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
17808
17809         $LFS mkdir -i 0 -c 1 $DIR/$tdir
17810         $LFS setstripe -d $DIR/$tdir
17811         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
17812                 error "Can't set directory default striping"
17813
17814         # exceed maximum stripe size
17815         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17816                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
17817         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
17818                 error "Able to create DoM component size more than LOD limit"
17819
17820         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
17821         dom_current=$(do_facet mds1 $LCTL get_param -n \
17822                                                 lod.$mdtname.dom_stripesize)
17823         [ 0 -eq ${dom_current} ] ||
17824                 error "Can't set zero DoM stripe limit"
17825         rm $dom
17826
17827         # attempt to create DoM file on server with disabled DoM should
17828         # remove DoM entry from layout and be succeed
17829         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
17830                 error "Can't create DoM file (DoM is disabled)"
17831         [ $($LFS getstripe -L $dom) == "mdt" ] &&
17832                 error "File has DoM component while DoM is disabled"
17833         rm $dom
17834
17835         # attempt to create DoM file with only DoM stripe should return error
17836         $LFS setstripe -E $dom_limit -L mdt $dom &&
17837                 error "Able to create DoM-only file while DoM is disabled"
17838
17839         # too low values to be aligned with smallest stripe size 64K
17840         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
17841         dom_current=$(do_facet mds1 $LCTL get_param -n \
17842                                                 lod.$mdtname.dom_stripesize)
17843         [ 30000 -eq ${dom_current} ] &&
17844                 error "Can set too small DoM stripe limit"
17845
17846         # 64K is a minimal stripe size in Lustre, expect limit of that size
17847         [ 65536 -eq ${dom_current} ] ||
17848                 error "Limit is not set to 64K but ${dom_current}"
17849
17850         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
17851         dom_current=$(do_facet mds1 $LCTL get_param -n \
17852                                                 lod.$mdtname.dom_stripesize)
17853         echo $dom_current
17854         [ 2147483648 -eq ${dom_current} ] &&
17855                 error "Can set too large DoM stripe limit"
17856
17857         do_facet mds1 $LCTL set_param -n \
17858                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
17859         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17860                 error "Can't create DoM component size after limit change"
17861         do_facet mds1 $LCTL set_param -n \
17862                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
17863         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
17864                 error "Can't create DoM file after limit decrease"
17865         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
17866                 error "Can create big DoM component after limit decrease"
17867         touch ${dom}_def ||
17868                 error "Can't create file with old default layout"
17869
17870         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
17871         return 0
17872 }
17873 run_test 270f "DoM: maximum DoM stripe size checks"
17874
17875 test_271a() {
17876         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17877                 skip "Need MDS version at least 2.10.55"
17878
17879         local dom=$DIR/$tdir/dom
17880
17881         mkdir -p $DIR/$tdir
17882
17883         $LFS setstripe -E 1024K -L mdt $dom
17884
17885         lctl set_param -n mdc.*.stats=clear
17886         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17887         cat $dom > /dev/null
17888         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
17889         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
17890         ls $dom
17891         rm -f $dom
17892 }
17893 run_test 271a "DoM: data is cached for read after write"
17894
17895 test_271b() {
17896         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17897                 skip "Need MDS version at least 2.10.55"
17898
17899         local dom=$DIR/$tdir/dom
17900
17901         mkdir -p $DIR/$tdir
17902
17903         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17904
17905         lctl set_param -n mdc.*.stats=clear
17906         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17907         cancel_lru_locks mdc
17908         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
17909         # second stat to check size is cached on client
17910         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
17911         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17912         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
17913         rm -f $dom
17914 }
17915 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
17916
17917 test_271ba() {
17918         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17919                 skip "Need MDS version at least 2.10.55"
17920
17921         local dom=$DIR/$tdir/dom
17922
17923         mkdir -p $DIR/$tdir
17924
17925         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17926
17927         lctl set_param -n mdc.*.stats=clear
17928         lctl set_param -n osc.*.stats=clear
17929         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
17930         cancel_lru_locks mdc
17931         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17932         # second stat to check size is cached on client
17933         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17934         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17935         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
17936         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
17937         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
17938         rm -f $dom
17939 }
17940 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
17941
17942
17943 get_mdc_stats() {
17944         local mdtidx=$1
17945         local param=$2
17946         local mdt=MDT$(printf %04x $mdtidx)
17947
17948         if [ -z $param ]; then
17949                 lctl get_param -n mdc.*$mdt*.stats
17950         else
17951                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
17952         fi
17953 }
17954
17955 test_271c() {
17956         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17957                 skip "Need MDS version at least 2.10.55"
17958
17959         local dom=$DIR/$tdir/dom
17960
17961         mkdir -p $DIR/$tdir
17962
17963         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17964
17965         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17966         local facet=mds$((mdtidx + 1))
17967
17968         cancel_lru_locks mdc
17969         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
17970         createmany -o $dom 1000
17971         lctl set_param -n mdc.*.stats=clear
17972         smalliomany -w $dom 1000 200
17973         get_mdc_stats $mdtidx
17974         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17975         # Each file has 1 open, 1 IO enqueues, total 2000
17976         # but now we have also +1 getxattr for security.capability, total 3000
17977         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
17978         unlinkmany $dom 1000
17979
17980         cancel_lru_locks mdc
17981         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
17982         createmany -o $dom 1000
17983         lctl set_param -n mdc.*.stats=clear
17984         smalliomany -w $dom 1000 200
17985         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17986         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
17987         # for OPEN and IO lock.
17988         [ $((enq - enq_2)) -ge 1000 ] ||
17989                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
17990         unlinkmany $dom 1000
17991         return 0
17992 }
17993 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
17994
17995 cleanup_271def_tests() {
17996         trap 0
17997         rm -f $1
17998 }
17999
18000 test_271d() {
18001         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18002                 skip "Need MDS version at least 2.10.57"
18003
18004         local dom=$DIR/$tdir/dom
18005         local tmp=$TMP/$tfile
18006         trap "cleanup_271def_tests $tmp" EXIT
18007
18008         mkdir -p $DIR/$tdir
18009
18010         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18011
18012         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18013
18014         cancel_lru_locks mdc
18015         dd if=/dev/urandom of=$tmp bs=1000 count=1
18016         dd if=$tmp of=$dom bs=1000 count=1
18017         cancel_lru_locks mdc
18018
18019         cat /etc/hosts >> $tmp
18020         lctl set_param -n mdc.*.stats=clear
18021
18022         # append data to the same file it should update local page
18023         echo "Append to the same page"
18024         cat /etc/hosts >> $dom
18025         local num=$(get_mdc_stats $mdtidx ost_read)
18026         local ra=$(get_mdc_stats $mdtidx req_active)
18027         local rw=$(get_mdc_stats $mdtidx req_waittime)
18028
18029         [ -z $num ] || error "$num READ RPC occured"
18030         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18031         echo "... DONE"
18032
18033         # compare content
18034         cmp $tmp $dom || error "file miscompare"
18035
18036         cancel_lru_locks mdc
18037         lctl set_param -n mdc.*.stats=clear
18038
18039         echo "Open and read file"
18040         cat $dom > /dev/null
18041         local num=$(get_mdc_stats $mdtidx ost_read)
18042         local ra=$(get_mdc_stats $mdtidx req_active)
18043         local rw=$(get_mdc_stats $mdtidx req_waittime)
18044
18045         [ -z $num ] || error "$num READ RPC occured"
18046         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18047         echo "... DONE"
18048
18049         # compare content
18050         cmp $tmp $dom || error "file miscompare"
18051
18052         return 0
18053 }
18054 run_test 271d "DoM: read on open (1K file in reply buffer)"
18055
18056 test_271f() {
18057         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18058                 skip "Need MDS version at least 2.10.57"
18059
18060         local dom=$DIR/$tdir/dom
18061         local tmp=$TMP/$tfile
18062         trap "cleanup_271def_tests $tmp" EXIT
18063
18064         mkdir -p $DIR/$tdir
18065
18066         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18067
18068         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18069
18070         cancel_lru_locks mdc
18071         dd if=/dev/urandom of=$tmp bs=200000 count=1
18072         dd if=$tmp of=$dom bs=200000 count=1
18073         cancel_lru_locks mdc
18074         cat /etc/hosts >> $tmp
18075         lctl set_param -n mdc.*.stats=clear
18076
18077         echo "Append to the same page"
18078         cat /etc/hosts >> $dom
18079         local num=$(get_mdc_stats $mdtidx ost_read)
18080         local ra=$(get_mdc_stats $mdtidx req_active)
18081         local rw=$(get_mdc_stats $mdtidx req_waittime)
18082
18083         [ -z $num ] || error "$num READ RPC occured"
18084         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18085         echo "... DONE"
18086
18087         # compare content
18088         cmp $tmp $dom || error "file miscompare"
18089
18090         cancel_lru_locks mdc
18091         lctl set_param -n mdc.*.stats=clear
18092
18093         echo "Open and read file"
18094         cat $dom > /dev/null
18095         local num=$(get_mdc_stats $mdtidx ost_read)
18096         local ra=$(get_mdc_stats $mdtidx req_active)
18097         local rw=$(get_mdc_stats $mdtidx req_waittime)
18098
18099         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
18100         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18101         echo "... DONE"
18102
18103         # compare content
18104         cmp $tmp $dom || error "file miscompare"
18105
18106         return 0
18107 }
18108 run_test 271f "DoM: read on open (200K file and read tail)"
18109
18110 test_271g() {
18111         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
18112                 skip "Skipping due to old client or server version"
18113
18114         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
18115         # to get layout
18116         $CHECKSTAT -t file $DIR1/$tfile
18117
18118         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
18119         MULTIOP_PID=$!
18120         sleep 1
18121         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
18122         $LCTL set_param fail_loc=0x80000314
18123         rm $DIR1/$tfile || error "Unlink fails"
18124         RC=$?
18125         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
18126         [ $RC -eq 0 ] || error "Failed write to stale object"
18127 }
18128 run_test 271g "Discard DoM data vs client flush race"
18129
18130 test_272a() {
18131         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18132                 skip "Need MDS version at least 2.11.50"
18133
18134         local dom=$DIR/$tdir/dom
18135         mkdir -p $DIR/$tdir
18136
18137         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
18138         dd if=/dev/urandom of=$dom bs=512K count=1 ||
18139                 error "failed to write data into $dom"
18140         local old_md5=$(md5sum $dom)
18141
18142         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
18143                 error "failed to migrate to the same DoM component"
18144
18145         local new_md5=$(md5sum $dom)
18146
18147         [ "$old_md5" == "$new_md5" ] ||
18148                 error "md5sum differ: $old_md5, $new_md5"
18149
18150         [ $($LFS getstripe -c $dom) -eq 2 ] ||
18151                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
18152 }
18153 run_test 272a "DoM migration: new layout with the same DOM component"
18154
18155 test_272b() {
18156         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18157                 skip "Need MDS version at least 2.11.50"
18158
18159         local dom=$DIR/$tdir/dom
18160         mkdir -p $DIR/$tdir
18161         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18162
18163         local mdtidx=$($LFS getstripe -m $dom)
18164         local mdtname=MDT$(printf %04x $mdtidx)
18165         local facet=mds$((mdtidx + 1))
18166
18167         local mdtfree1=$(do_facet $facet \
18168                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18169         dd if=/dev/urandom of=$dom bs=2M count=1 ||
18170                 error "failed to write data into $dom"
18171         local old_md5=$(md5sum $dom)
18172         cancel_lru_locks mdc
18173         local mdtfree1=$(do_facet $facet \
18174                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18175
18176         $LFS migrate -c2 $dom ||
18177                 error "failed to migrate to the new composite layout"
18178         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
18179                 error "MDT stripe was not removed"
18180
18181         cancel_lru_locks mdc
18182         local new_md5=$(md5sum $dom)
18183         [ "$old_md5" != "$new_md5" ] &&
18184                 error "$old_md5 != $new_md5"
18185
18186         # Skip free space checks with ZFS
18187         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18188                 local mdtfree2=$(do_facet $facet \
18189                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18190                 [ $mdtfree2 -gt $mdtfree1 ] ||
18191                         error "MDT space is not freed after migration"
18192         fi
18193         return 0
18194 }
18195 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
18196
18197 test_272c() {
18198         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18199                 skip "Need MDS version at least 2.11.50"
18200
18201         local dom=$DIR/$tdir/$tfile
18202         mkdir -p $DIR/$tdir
18203         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18204
18205         local mdtidx=$($LFS getstripe -m $dom)
18206         local mdtname=MDT$(printf %04x $mdtidx)
18207         local facet=mds$((mdtidx + 1))
18208
18209         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
18210                 error "failed to write data into $dom"
18211         local old_md5=$(md5sum $dom)
18212         cancel_lru_locks mdc
18213         local mdtfree1=$(do_facet $facet \
18214                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18215
18216         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
18217                 error "failed to migrate to the new composite layout"
18218         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
18219                 error "MDT stripe was not removed"
18220
18221         cancel_lru_locks mdc
18222         local new_md5=$(md5sum $dom)
18223         [ "$old_md5" != "$new_md5" ] &&
18224                 error "$old_md5 != $new_md5"
18225
18226         # Skip free space checks with ZFS
18227         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18228                 local mdtfree2=$(do_facet $facet \
18229                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18230                 [ $mdtfree2 -gt $mdtfree1 ] ||
18231                         error "MDS space is not freed after migration"
18232         fi
18233         return 0
18234 }
18235 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
18236
18237 test_273a() {
18238         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18239                 skip "Need MDS version at least 2.11.50"
18240
18241         # Layout swap cannot be done if either file has DOM component,
18242         # this will never be supported, migration should be used instead
18243
18244         local dom=$DIR/$tdir/$tfile
18245         mkdir -p $DIR/$tdir
18246
18247         $LFS setstripe -c2 ${dom}_plain
18248         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
18249         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
18250                 error "can swap layout with DoM component"
18251         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
18252                 error "can swap layout with DoM component"
18253
18254         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
18255         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
18256                 error "can swap layout with DoM component"
18257         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
18258                 error "can swap layout with DoM component"
18259         return 0
18260 }
18261 run_test 273a "DoM: layout swapping should fail with DOM"
18262
18263 test_275() {
18264         remote_ost_nodsh && skip "remote OST with nodsh"
18265         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
18266                 skip "Need OST version >= 2.10.57"
18267
18268         local file=$DIR/$tfile
18269         local oss
18270
18271         oss=$(comma_list $(osts_nodes))
18272
18273         dd if=/dev/urandom of=$file bs=1M count=2 ||
18274                 error "failed to create a file"
18275         cancel_lru_locks osc
18276
18277         #lock 1
18278         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
18279                 error "failed to read a file"
18280
18281 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
18282         $LCTL set_param fail_loc=0x8000031f
18283
18284         cancel_lru_locks osc &
18285         sleep 1
18286
18287 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
18288         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
18289         #IO takes another lock, but matches the PENDING one
18290         #and places it to the IO RPC
18291         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
18292                 error "failed to read a file with PENDING lock"
18293 }
18294 run_test 275 "Read on a canceled duplicate lock"
18295
18296 test_276() {
18297         remote_ost_nodsh && skip "remote OST with nodsh"
18298         local pid
18299
18300         do_facet ost1 "(while true; do \
18301                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
18302                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
18303         pid=$!
18304
18305         for LOOP in $(seq 20); do
18306                 stop ost1
18307                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
18308         done
18309         kill -9 $pid
18310         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
18311                 rm $TMP/sanity_276_pid"
18312 }
18313 run_test 276 "Race between mount and obd_statfs"
18314
18315 cleanup_test_300() {
18316         trap 0
18317         umask $SAVE_UMASK
18318 }
18319 test_striped_dir() {
18320         local mdt_index=$1
18321         local stripe_count
18322         local stripe_index
18323
18324         mkdir -p $DIR/$tdir
18325
18326         SAVE_UMASK=$(umask)
18327         trap cleanup_test_300 RETURN EXIT
18328
18329         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
18330                                                 $DIR/$tdir/striped_dir ||
18331                 error "set striped dir error"
18332
18333         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
18334         [ "$mode" = "755" ] || error "expect 755 got $mode"
18335
18336         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
18337                 error "getdirstripe failed"
18338         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
18339         if [ "$stripe_count" != "2" ]; then
18340                 error "1:stripe_count is $stripe_count, expect 2"
18341         fi
18342         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
18343         if [ "$stripe_count" != "2" ]; then
18344                 error "2:stripe_count is $stripe_count, expect 2"
18345         fi
18346
18347         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
18348         if [ "$stripe_index" != "$mdt_index" ]; then
18349                 error "stripe_index is $stripe_index, expect $mdt_index"
18350         fi
18351
18352         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
18353                 error "nlink error after create striped dir"
18354
18355         mkdir $DIR/$tdir/striped_dir/a
18356         mkdir $DIR/$tdir/striped_dir/b
18357
18358         stat $DIR/$tdir/striped_dir/a ||
18359                 error "create dir under striped dir failed"
18360         stat $DIR/$tdir/striped_dir/b ||
18361                 error "create dir under striped dir failed"
18362
18363         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
18364                 error "nlink error after mkdir"
18365
18366         rmdir $DIR/$tdir/striped_dir/a
18367         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
18368                 error "nlink error after rmdir"
18369
18370         rmdir $DIR/$tdir/striped_dir/b
18371         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
18372                 error "nlink error after rmdir"
18373
18374         chattr +i $DIR/$tdir/striped_dir
18375         createmany -o $DIR/$tdir/striped_dir/f 10 &&
18376                 error "immutable flags not working under striped dir!"
18377         chattr -i $DIR/$tdir/striped_dir
18378
18379         rmdir $DIR/$tdir/striped_dir ||
18380                 error "rmdir striped dir error"
18381
18382         cleanup_test_300
18383
18384         true
18385 }
18386
18387 test_300a() {
18388         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18389                 skip "skipped for lustre < 2.7.0"
18390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18391         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18392
18393         test_striped_dir 0 || error "failed on striped dir on MDT0"
18394         test_striped_dir 1 || error "failed on striped dir on MDT0"
18395 }
18396 run_test 300a "basic striped dir sanity test"
18397
18398 test_300b() {
18399         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18400                 skip "skipped for lustre < 2.7.0"
18401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18402         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18403
18404         local i
18405         local mtime1
18406         local mtime2
18407         local mtime3
18408
18409         test_mkdir $DIR/$tdir || error "mkdir fail"
18410         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18411                 error "set striped dir error"
18412         for i in {0..9}; do
18413                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
18414                 sleep 1
18415                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
18416                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
18417                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
18418                 sleep 1
18419                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
18420                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
18421                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
18422         done
18423         true
18424 }
18425 run_test 300b "check ctime/mtime for striped dir"
18426
18427 test_300c() {
18428         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18429                 skip "skipped for lustre < 2.7.0"
18430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18431         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18432
18433         local file_count
18434
18435         mkdir -p $DIR/$tdir
18436         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
18437                 error "set striped dir error"
18438
18439         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
18440                 error "chown striped dir failed"
18441
18442         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
18443                 error "create 5k files failed"
18444
18445         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
18446
18447         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
18448
18449         rm -rf $DIR/$tdir
18450 }
18451 run_test 300c "chown && check ls under striped directory"
18452
18453 test_300d() {
18454         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18455                 skip "skipped for lustre < 2.7.0"
18456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18457         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18458
18459         local stripe_count
18460         local file
18461
18462         mkdir -p $DIR/$tdir
18463         $LFS setstripe -c 2 $DIR/$tdir
18464
18465         #local striped directory
18466         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18467                 error "set striped dir error"
18468         createmany -o $DIR/$tdir/striped_dir/f 10 ||
18469                 error "create 10 files failed"
18470
18471         #remote striped directory
18472         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
18473                 error "set striped dir error"
18474         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
18475                 error "create 10 files failed"
18476
18477         for file in $(find $DIR/$tdir); do
18478                 stripe_count=$($LFS getstripe -c $file)
18479                 [ $stripe_count -eq 2 ] ||
18480                         error "wrong stripe $stripe_count for $file"
18481         done
18482
18483         rm -rf $DIR/$tdir
18484 }
18485 run_test 300d "check default stripe under striped directory"
18486
18487 test_300e() {
18488         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18489                 skip "Need MDS version at least 2.7.55"
18490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18491         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18492
18493         local stripe_count
18494         local file
18495
18496         mkdir -p $DIR/$tdir
18497
18498         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18499                 error "set striped dir error"
18500
18501         touch $DIR/$tdir/striped_dir/a
18502         touch $DIR/$tdir/striped_dir/b
18503         touch $DIR/$tdir/striped_dir/c
18504
18505         mkdir $DIR/$tdir/striped_dir/dir_a
18506         mkdir $DIR/$tdir/striped_dir/dir_b
18507         mkdir $DIR/$tdir/striped_dir/dir_c
18508
18509         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
18510                 error "set striped adir under striped dir error"
18511
18512         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
18513                 error "set striped bdir under striped dir error"
18514
18515         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
18516                 error "set striped cdir under striped dir error"
18517
18518         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
18519                 error "rename dir under striped dir fails"
18520
18521         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
18522                 error "rename dir under different stripes fails"
18523
18524         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
18525                 error "rename file under striped dir should succeed"
18526
18527         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
18528                 error "rename dir under striped dir should succeed"
18529
18530         rm -rf $DIR/$tdir
18531 }
18532 run_test 300e "check rename under striped directory"
18533
18534 test_300f() {
18535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18536         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18537         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18538                 skip "Need MDS version at least 2.7.55"
18539
18540         local stripe_count
18541         local file
18542
18543         rm -rf $DIR/$tdir
18544         mkdir -p $DIR/$tdir
18545
18546         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18547                 error "set striped dir error"
18548
18549         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
18550                 error "set striped dir error"
18551
18552         touch $DIR/$tdir/striped_dir/a
18553         mkdir $DIR/$tdir/striped_dir/dir_a
18554         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
18555                 error "create striped dir under striped dir fails"
18556
18557         touch $DIR/$tdir/striped_dir1/b
18558         mkdir $DIR/$tdir/striped_dir1/dir_b
18559         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
18560                 error "create striped dir under striped dir fails"
18561
18562         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
18563                 error "rename dir under different striped dir should fail"
18564
18565         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
18566                 error "rename striped dir under diff striped dir should fail"
18567
18568         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
18569                 error "rename file under diff striped dirs fails"
18570
18571         rm -rf $DIR/$tdir
18572 }
18573 run_test 300f "check rename cross striped directory"
18574
18575 test_300_check_default_striped_dir()
18576 {
18577         local dirname=$1
18578         local default_count=$2
18579         local default_index=$3
18580         local stripe_count
18581         local stripe_index
18582         local dir_stripe_index
18583         local dir
18584
18585         echo "checking $dirname $default_count $default_index"
18586         $LFS setdirstripe -D -c $default_count -i $default_index \
18587                                 -t all_char $DIR/$tdir/$dirname ||
18588                 error "set default stripe on striped dir error"
18589         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
18590         [ $stripe_count -eq $default_count ] ||
18591                 error "expect $default_count get $stripe_count for $dirname"
18592
18593         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
18594         [ $stripe_index -eq $default_index ] ||
18595                 error "expect $default_index get $stripe_index for $dirname"
18596
18597         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
18598                                                 error "create dirs failed"
18599
18600         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
18601         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
18602         for dir in $(find $DIR/$tdir/$dirname/*); do
18603                 stripe_count=$($LFS getdirstripe -c $dir)
18604                 [ $stripe_count -eq $default_count ] ||
18605                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
18606                 error "stripe count $default_count != $stripe_count for $dir"
18607
18608                 stripe_index=$($LFS getdirstripe -i $dir)
18609                 [ $default_index -eq -1 ] ||
18610                         [ $stripe_index -eq $default_index ] ||
18611                         error "$stripe_index != $default_index for $dir"
18612
18613                 #check default stripe
18614                 stripe_count=$($LFS getdirstripe -D -c $dir)
18615                 [ $stripe_count -eq $default_count ] ||
18616                 error "default count $default_count != $stripe_count for $dir"
18617
18618                 stripe_index=$($LFS getdirstripe -D -i $dir)
18619                 [ $stripe_index -eq $default_index ] ||
18620                 error "default index $default_index != $stripe_index for $dir"
18621         done
18622         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
18623 }
18624
18625 test_300g() {
18626         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18627         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18628                 skip "Need MDS version at least 2.7.55"
18629
18630         local dir
18631         local stripe_count
18632         local stripe_index
18633
18634         mkdir $DIR/$tdir
18635         mkdir $DIR/$tdir/normal_dir
18636
18637         #Checking when client cache stripe index
18638         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
18639         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
18640                 error "create striped_dir failed"
18641
18642         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
18643                 error "create dir0 fails"
18644         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
18645         [ $stripe_index -eq 0 ] ||
18646                 error "dir0 expect index 0 got $stripe_index"
18647
18648         mkdir $DIR/$tdir/striped_dir/dir1 ||
18649                 error "create dir1 fails"
18650         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
18651         [ $stripe_index -eq 1 ] ||
18652                 error "dir1 expect index 1 got $stripe_index"
18653
18654         #check default stripe count/stripe index
18655         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
18656         test_300_check_default_striped_dir normal_dir 1 0
18657         test_300_check_default_striped_dir normal_dir 2 1
18658         test_300_check_default_striped_dir normal_dir 2 -1
18659
18660         #delete default stripe information
18661         echo "delete default stripeEA"
18662         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
18663                 error "set default stripe on striped dir error"
18664
18665         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
18666         for dir in $(find $DIR/$tdir/normal_dir/*); do
18667                 stripe_count=$($LFS getdirstripe -c $dir)
18668                 [ $stripe_count -eq 0 ] ||
18669                         error "expect 1 get $stripe_count for $dir"
18670                 stripe_index=$($LFS getdirstripe -i $dir)
18671                 [ $stripe_index -eq 0 ] ||
18672                         error "expect 0 get $stripe_index for $dir"
18673         done
18674 }
18675 run_test 300g "check default striped directory for normal directory"
18676
18677 test_300h() {
18678         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18679         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18680                 skip "Need MDS version at least 2.7.55"
18681
18682         local dir
18683         local stripe_count
18684
18685         mkdir $DIR/$tdir
18686         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18687                 error "set striped dir error"
18688
18689         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
18690         test_300_check_default_striped_dir striped_dir 1 0
18691         test_300_check_default_striped_dir striped_dir 2 1
18692         test_300_check_default_striped_dir striped_dir 2 -1
18693
18694         #delete default stripe information
18695         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
18696                 error "set default stripe on striped dir error"
18697
18698         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
18699         for dir in $(find $DIR/$tdir/striped_dir/*); do
18700                 stripe_count=$($LFS getdirstripe -c $dir)
18701                 [ $stripe_count -eq 0 ] ||
18702                         error "expect 1 get $stripe_count for $dir"
18703         done
18704 }
18705 run_test 300h "check default striped directory for striped directory"
18706
18707 test_300i() {
18708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18709         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18710         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18711                 skip "Need MDS version at least 2.7.55"
18712
18713         local stripe_count
18714         local file
18715
18716         mkdir $DIR/$tdir
18717
18718         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18719                 error "set striped dir error"
18720
18721         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18722                 error "create files under striped dir failed"
18723
18724         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
18725                 error "set striped hashdir error"
18726
18727         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
18728                 error "create dir0 under hash dir failed"
18729         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
18730                 error "create dir1 under hash dir failed"
18731
18732         # unfortunately, we need to umount to clear dir layout cache for now
18733         # once we fully implement dir layout, we can drop this
18734         umount_client $MOUNT || error "umount failed"
18735         mount_client $MOUNT || error "mount failed"
18736
18737         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
18738         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
18739         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
18740
18741         #set the stripe to be unknown hash type
18742         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
18743         $LCTL set_param fail_loc=0x1901
18744         for ((i = 0; i < 10; i++)); do
18745                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
18746                         error "stat f-$i failed"
18747                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
18748         done
18749
18750         touch $DIR/$tdir/striped_dir/f0 &&
18751                 error "create under striped dir with unknown hash should fail"
18752
18753         $LCTL set_param fail_loc=0
18754
18755         umount_client $MOUNT || error "umount failed"
18756         mount_client $MOUNT || error "mount failed"
18757
18758         return 0
18759 }
18760 run_test 300i "client handle unknown hash type striped directory"
18761
18762 test_300j() {
18763         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18765         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18766                 skip "Need MDS version at least 2.7.55"
18767
18768         local stripe_count
18769         local file
18770
18771         mkdir $DIR/$tdir
18772
18773         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
18774         $LCTL set_param fail_loc=0x1702
18775         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18776                 error "set striped dir error"
18777
18778         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18779                 error "create files under striped dir failed"
18780
18781         $LCTL set_param fail_loc=0
18782
18783         rm -rf $DIR/$tdir || error "unlink striped dir fails"
18784
18785         return 0
18786 }
18787 run_test 300j "test large update record"
18788
18789 test_300k() {
18790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18791         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18792         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18793                 skip "Need MDS version at least 2.7.55"
18794
18795         # this test needs a huge transaction
18796         local kb
18797         kb=$(do_facet $SINGLEMDS lctl get_param -n osd*.lustre-MDT0000.kbytestotal)
18798         [ $kb -lt $((1024*1024)) ] && skip "too small mds: $kb"
18799
18800         local stripe_count
18801         local file
18802
18803         mkdir $DIR/$tdir
18804
18805         #define OBD_FAIL_LARGE_STRIPE   0x1703
18806         $LCTL set_param fail_loc=0x1703
18807         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
18808                 error "set striped dir error"
18809         $LCTL set_param fail_loc=0
18810
18811         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18812                 error "getstripeddir fails"
18813         rm -rf $DIR/$tdir/striped_dir ||
18814                 error "unlink striped dir fails"
18815
18816         return 0
18817 }
18818 run_test 300k "test large striped directory"
18819
18820 test_300l() {
18821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18822         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18823         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18824                 skip "Need MDS version at least 2.7.55"
18825
18826         local stripe_index
18827
18828         test_mkdir -p $DIR/$tdir/striped_dir
18829         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
18830                         error "chown $RUNAS_ID failed"
18831         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
18832                 error "set default striped dir failed"
18833
18834         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
18835         $LCTL set_param fail_loc=0x80000158
18836         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
18837
18838         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
18839         [ $stripe_index -eq 1 ] ||
18840                 error "expect 1 get $stripe_index for $dir"
18841 }
18842 run_test 300l "non-root user to create dir under striped dir with stale layout"
18843
18844 test_300m() {
18845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18846         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
18847         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18848                 skip "Need MDS version at least 2.7.55"
18849
18850         mkdir -p $DIR/$tdir/striped_dir
18851         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
18852                 error "set default stripes dir error"
18853
18854         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
18855
18856         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
18857         [ $stripe_count -eq 0 ] ||
18858                         error "expect 0 get $stripe_count for a"
18859
18860         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
18861                 error "set default stripes dir error"
18862
18863         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
18864
18865         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
18866         [ $stripe_count -eq 0 ] ||
18867                         error "expect 0 get $stripe_count for b"
18868
18869         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
18870                 error "set default stripes dir error"
18871
18872         mkdir $DIR/$tdir/striped_dir/c &&
18873                 error "default stripe_index is invalid, mkdir c should fails"
18874
18875         rm -rf $DIR/$tdir || error "rmdir fails"
18876 }
18877 run_test 300m "setstriped directory on single MDT FS"
18878
18879 cleanup_300n() {
18880         local list=$(comma_list $(mdts_nodes))
18881
18882         trap 0
18883         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18884 }
18885
18886 test_300n() {
18887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18888         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18889         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18890                 skip "Need MDS version at least 2.7.55"
18891         remote_mds_nodsh && skip "remote MDS with nodsh"
18892
18893         local stripe_index
18894         local list=$(comma_list $(mdts_nodes))
18895
18896         trap cleanup_300n RETURN EXIT
18897         mkdir -p $DIR/$tdir
18898         chmod 777 $DIR/$tdir
18899         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
18900                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18901                 error "create striped dir succeeds with gid=0"
18902
18903         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18904         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
18905                 error "create striped dir fails with gid=-1"
18906
18907         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18908         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
18909                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18910                 error "set default striped dir succeeds with gid=0"
18911
18912
18913         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18914         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
18915                 error "set default striped dir fails with gid=-1"
18916
18917
18918         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18919         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
18920                                         error "create test_dir fails"
18921         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
18922                                         error "create test_dir1 fails"
18923         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
18924                                         error "create test_dir2 fails"
18925         cleanup_300n
18926 }
18927 run_test 300n "non-root user to create dir under striped dir with default EA"
18928
18929 test_300o() {
18930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18931         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18932         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18933                 skip "Need MDS version at least 2.7.55"
18934
18935         local numfree1
18936         local numfree2
18937
18938         mkdir -p $DIR/$tdir
18939
18940         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
18941         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
18942         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
18943                 skip "not enough free inodes $numfree1 $numfree2"
18944         fi
18945
18946         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
18947         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
18948         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
18949                 skip "not enough free space $numfree1 $numfree2"
18950         fi
18951
18952         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
18953                 error "setdirstripe fails"
18954
18955         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
18956                 error "create dirs fails"
18957
18958         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
18959         ls $DIR/$tdir/striped_dir > /dev/null ||
18960                 error "ls striped dir fails"
18961         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
18962                 error "unlink big striped dir fails"
18963 }
18964 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
18965
18966 test_300p() {
18967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18968         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18969         remote_mds_nodsh && skip "remote MDS with nodsh"
18970
18971         mkdir -p $DIR/$tdir
18972
18973         #define OBD_FAIL_OUT_ENOSPC     0x1704
18974         do_facet mds2 lctl set_param fail_loc=0x80001704
18975         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
18976                  && error "create striped directory should fail"
18977
18978         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
18979
18980         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
18981         true
18982 }
18983 run_test 300p "create striped directory without space"
18984
18985 test_300q() {
18986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18987         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18988
18989         local fd=$(free_fd)
18990         local cmd="exec $fd<$tdir"
18991         cd $DIR
18992         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
18993         eval $cmd
18994         cmd="exec $fd<&-"
18995         trap "eval $cmd" EXIT
18996         cd $tdir || error "cd $tdir fails"
18997         rmdir  ../$tdir || error "rmdir $tdir fails"
18998         mkdir local_dir && error "create dir succeeds"
18999         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
19000         eval $cmd
19001         return 0
19002 }
19003 run_test 300q "create remote directory under orphan directory"
19004
19005 test_300r() {
19006         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
19007                 skip "Need MDS version at least 2.7.55" && return
19008         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19009
19010         mkdir $DIR/$tdir
19011
19012         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
19013                 error "set striped dir error"
19014
19015         $LFS getdirstripe $DIR/$tdir/striped_dir ||
19016                 error "getstripeddir fails"
19017
19018         local stripe_count
19019         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19020                       awk '/lmv_stripe_count:/ { print $2 }')
19021
19022         [ $MDSCOUNT -ne $stripe_count ] &&
19023                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
19024
19025         rm -rf $DIR/$tdir/striped_dir ||
19026                 error "unlink striped dir fails"
19027 }
19028 run_test 300r "test -1 striped directory"
19029
19030 prepare_remote_file() {
19031         mkdir $DIR/$tdir/src_dir ||
19032                 error "create remote source failed"
19033
19034         cp /etc/hosts $DIR/$tdir/src_dir/a ||
19035                  error "cp to remote source failed"
19036         touch $DIR/$tdir/src_dir/a
19037
19038         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
19039                 error "create remote target dir failed"
19040
19041         touch $DIR/$tdir/tgt_dir/b
19042
19043         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
19044                 error "rename dir cross MDT failed!"
19045
19046         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
19047                 error "src_child still exists after rename"
19048
19049         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
19050                 error "missing file(a) after rename"
19051
19052         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
19053                 error "diff after rename"
19054 }
19055
19056 test_310a() {
19057         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19059
19060         local remote_file=$DIR/$tdir/tgt_dir/b
19061
19062         mkdir -p $DIR/$tdir
19063
19064         prepare_remote_file || error "prepare remote file failed"
19065
19066         #open-unlink file
19067         $OPENUNLINK $remote_file $remote_file ||
19068                 error "openunlink $remote_file failed"
19069         $CHECKSTAT -a $remote_file || error "$remote_file exists"
19070 }
19071 run_test 310a "open unlink remote file"
19072
19073 test_310b() {
19074         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19076
19077         local remote_file=$DIR/$tdir/tgt_dir/b
19078
19079         mkdir -p $DIR/$tdir
19080
19081         prepare_remote_file || error "prepare remote file failed"
19082
19083         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19084         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
19085         $CHECKSTAT -t file $remote_file || error "check file failed"
19086 }
19087 run_test 310b "unlink remote file with multiple links while open"
19088
19089 test_310c() {
19090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19091         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
19092
19093         local remote_file=$DIR/$tdir/tgt_dir/b
19094
19095         mkdir -p $DIR/$tdir
19096
19097         prepare_remote_file || error "prepare remote file failed"
19098
19099         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19100         multiop_bg_pause $remote_file O_uc ||
19101                         error "mulitop failed for remote file"
19102         MULTIPID=$!
19103         $MULTIOP $DIR/$tfile Ouc
19104         kill -USR1 $MULTIPID
19105         wait $MULTIPID
19106 }
19107 run_test 310c "open-unlink remote file with multiple links"
19108
19109 #LU-4825
19110 test_311() {
19111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19112         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
19113         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
19114                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
19115         remote_mds_nodsh && skip "remote MDS with nodsh"
19116
19117         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19118         local mdts=$(comma_list $(mdts_nodes))
19119
19120         mkdir -p $DIR/$tdir
19121         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19122         createmany -o $DIR/$tdir/$tfile. 1000
19123
19124         # statfs data is not real time, let's just calculate it
19125         old_iused=$((old_iused + 1000))
19126
19127         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19128                         osp.*OST0000*MDT0000.create_count")
19129         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19130                                 osp.*OST0000*MDT0000.max_create_count")
19131         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
19132
19133         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
19134         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
19135         [ $index -ne 0 ] || error "$tfile stripe index is 0"
19136
19137         unlinkmany $DIR/$tdir/$tfile. 1000
19138
19139         do_nodes $mdts "$LCTL set_param -n \
19140                         osp.*OST0000*.max_create_count=$max_count"
19141         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
19142                 do_nodes $mdts "$LCTL set_param -n \
19143                                 osp.*OST0000*.create_count=$count"
19144         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
19145                         grep "=0" && error "create_count is zero"
19146
19147         local new_iused
19148         for i in $(seq 120); do
19149                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19150                 # system may be too busy to destroy all objs in time, use
19151                 # a somewhat small value to not fail autotest
19152                 [ $((old_iused - new_iused)) -gt 400 ] && break
19153                 sleep 1
19154         done
19155
19156         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
19157         [ $((old_iused - new_iused)) -gt 400 ] ||
19158                 error "objs not destroyed after unlink"
19159 }
19160 run_test 311 "disable OSP precreate, and unlink should destroy objs"
19161
19162 zfs_oid_to_objid()
19163 {
19164         local ost=$1
19165         local objid=$2
19166
19167         local vdevdir=$(dirname $(facet_vdevice $ost))
19168         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
19169         local zfs_zapid=$(do_facet $ost $cmd |
19170                           grep -w "/O/0/d$((objid%32))" -C 5 |
19171                           awk '/Object/{getline; print $1}')
19172         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
19173                           awk "/$objid = /"'{printf $3}')
19174
19175         echo $zfs_objid
19176 }
19177
19178 zfs_object_blksz() {
19179         local ost=$1
19180         local objid=$2
19181
19182         local vdevdir=$(dirname $(facet_vdevice $ost))
19183         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
19184         local blksz=$(do_facet $ost $cmd $objid |
19185                       awk '/dblk/{getline; printf $4}')
19186
19187         case "${blksz: -1}" in
19188                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
19189                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
19190                 *) ;;
19191         esac
19192
19193         echo $blksz
19194 }
19195
19196 test_312() { # LU-4856
19197         remote_ost_nodsh && skip "remote OST with nodsh"
19198         [ "$ost1_FSTYPE" = "zfs" ] ||
19199                 skip_env "the test only applies to zfs"
19200
19201         local max_blksz=$(do_facet ost1 \
19202                           $ZFS get -p recordsize $(facet_device ost1) |
19203                           awk '!/VALUE/{print $3}')
19204
19205         # to make life a little bit easier
19206         $LFS mkdir -c 1 -i 0 $DIR/$tdir
19207         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19208
19209         local tf=$DIR/$tdir/$tfile
19210         touch $tf
19211         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19212
19213         # Get ZFS object id
19214         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19215         # block size change by sequential overwrite
19216         local bs
19217
19218         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
19219                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
19220
19221                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
19222                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
19223         done
19224         rm -f $tf
19225
19226         # block size change by sequential append write
19227         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
19228         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19229         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19230         local count
19231
19232         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
19233                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
19234                         oflag=sync conv=notrunc
19235
19236                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
19237                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
19238                         error "blksz error, actual $blksz, " \
19239                                 "expected: 2 * $count * $PAGE_SIZE"
19240         done
19241         rm -f $tf
19242
19243         # random write
19244         touch $tf
19245         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19246         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19247
19248         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
19249         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19250         [ $blksz -eq $PAGE_SIZE ] ||
19251                 error "blksz error: $blksz, expected: $PAGE_SIZE"
19252
19253         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
19254         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19255         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
19256
19257         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
19258         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19259         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
19260 }
19261 run_test 312 "make sure ZFS adjusts its block size by write pattern"
19262
19263 test_313() {
19264         remote_ost_nodsh && skip "remote OST with nodsh"
19265
19266         local file=$DIR/$tfile
19267
19268         rm -f $file
19269         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
19270
19271         # define OBD_FAIL_TGT_RCVD_EIO           0x720
19272         do_facet ost1 "$LCTL set_param fail_loc=0x720"
19273         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
19274                 error "write should failed"
19275         do_facet ost1 "$LCTL set_param fail_loc=0"
19276         rm -f $file
19277 }
19278 run_test 313 "io should fail after last_rcvd update fail"
19279
19280 test_314() {
19281         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
19282
19283         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
19284         do_facet ost1 "$LCTL set_param fail_loc=0x720"
19285         rm -f $DIR/$tfile
19286         wait_delete_completed
19287         do_facet ost1 "$LCTL set_param fail_loc=0"
19288 }
19289 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
19290
19291 test_315() { # LU-618
19292         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
19293
19294         local file=$DIR/$tfile
19295         rm -f $file
19296
19297         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
19298                 error "multiop file write failed"
19299         $MULTIOP $file oO_RDONLY:r4063232_c &
19300         PID=$!
19301
19302         sleep 2
19303
19304         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
19305         kill -USR1 $PID
19306
19307         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
19308         rm -f $file
19309 }
19310 run_test 315 "read should be accounted"
19311
19312 test_316() {
19313         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19314         large_xattr_enabled || skip_env "ea_inode feature disabled"
19315
19316         rm -rf $DIR/$tdir/d
19317         mkdir -p $DIR/$tdir/d
19318         chown nobody $DIR/$tdir/d
19319         touch $DIR/$tdir/d/file
19320
19321         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
19322 }
19323 run_test 316 "lfs mv"
19324
19325 test_317() {
19326         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
19327                 skip "Need MDS version at least 2.11.53"
19328         local trunc_sz
19329         local grant_blk_size
19330
19331         if [ "$(facet_fstype $facet)" == "zfs" ]; then
19332                 skip "LU-10370: no implementation for ZFS" && return
19333         fi
19334
19335         stack_trap "rm -f $DIR/$tfile" EXIT
19336         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
19337                         awk '/grant_block_size:/ { print $2; exit; }')
19338         #
19339         # Create File of size 5M. Truncate it to below size's and verify
19340         # blocks count.
19341         #
19342         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
19343                 error "Create file : $DIR/$tfile"
19344
19345         for trunc_sz in 2097152 4097 4000 509 0; do
19346                 $TRUNCATE $DIR/$tfile $trunc_sz ||
19347                         error "truncate $tfile to $trunc_sz failed"
19348                 local sz=$(stat --format=%s $DIR/$tfile)
19349                 local blk=$(stat --format=%b $DIR/$tfile)
19350                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
19351                                      grant_blk_size) * 8))
19352
19353                 if [[ $blk -ne $trunc_blk ]]; then
19354                         $(which stat) $DIR/$tfile
19355                         error "Expected Block $trunc_blk got $blk for $tfile"
19356                 fi
19357
19358                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
19359                         error "Expected Size $trunc_sz got $sz for $tfile"
19360         done
19361
19362         #
19363         # sparse file test
19364         # Create file with a hole and write actual two blocks. Block count
19365         # must be 16.
19366         #
19367         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
19368                 conv=fsync || error "Create file : $DIR/$tfile"
19369
19370         # Calculate the final truncate size.
19371         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
19372
19373         #
19374         # truncate to size $trunc_sz bytes. Strip the last block
19375         # The block count must drop to 8
19376         #
19377         $TRUNCATE $DIR/$tfile $trunc_sz ||
19378                 error "truncate $tfile to $trunc_sz failed"
19379
19380         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
19381         sz=$(stat --format=%s $DIR/$tfile)
19382         blk=$(stat --format=%b $DIR/$tfile)
19383
19384         if [[ $blk -ne $trunc_bsz ]]; then
19385                 $(which stat) $DIR/$tfile
19386                 error "Expected Block $trunc_bsz got $blk for $tfile"
19387         fi
19388
19389         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
19390                 error "Expected Size $trunc_sz got $sz for $tfile"
19391 }
19392 run_test 317 "Verify blocks get correctly update after truncate"
19393
19394 test_319() {
19395         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
19396
19397         local before=$(date +%s)
19398         local evict
19399         local mdir=$DIR/$tdir
19400         local file=$mdir/xxx
19401
19402         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
19403         touch $file
19404
19405 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
19406         $LCTL set_param fail_val=5 fail_loc=0x8000032c
19407         $LFS mv -m1 $file &
19408
19409         sleep 1
19410         dd if=$file of=/dev/null
19411         wait
19412         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
19413           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
19414
19415         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
19416 }
19417 run_test 319 "lost lease lock on migrate error"
19418
19419 test_fake_rw() {
19420         local read_write=$1
19421         if [ "$read_write" = "write" ]; then
19422                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
19423         elif [ "$read_write" = "read" ]; then
19424                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
19425         else
19426                 error "argument error"
19427         fi
19428
19429         # turn off debug for performance testing
19430         local saved_debug=$($LCTL get_param -n debug)
19431         $LCTL set_param debug=0
19432
19433         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19434
19435         # get ost1 size - lustre-OST0000
19436         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
19437         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
19438         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
19439
19440         if [ "$read_write" = "read" ]; then
19441                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
19442         fi
19443
19444         local start_time=$(date +%s.%N)
19445         $dd_cmd bs=1M count=$blocks oflag=sync ||
19446                 error "real dd $read_write error"
19447         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
19448
19449         if [ "$read_write" = "write" ]; then
19450                 rm -f $DIR/$tfile
19451         fi
19452
19453         # define OBD_FAIL_OST_FAKE_RW           0x238
19454         do_facet ost1 $LCTL set_param fail_loc=0x238
19455
19456         local start_time=$(date +%s.%N)
19457         $dd_cmd bs=1M count=$blocks oflag=sync ||
19458                 error "fake dd $read_write error"
19459         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
19460
19461         if [ "$read_write" = "write" ]; then
19462                 # verify file size
19463                 cancel_lru_locks osc
19464                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
19465                         error "$tfile size not $blocks MB"
19466         fi
19467         do_facet ost1 $LCTL set_param fail_loc=0
19468
19469         echo "fake $read_write $duration_fake vs. normal $read_write" \
19470                 "$duration in seconds"
19471         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
19472                 error_not_in_vm "fake write is slower"
19473
19474         $LCTL set_param -n debug="$saved_debug"
19475         rm -f $DIR/$tfile
19476 }
19477 test_399a() { # LU-7655 for OST fake write
19478         remote_ost_nodsh && skip "remote OST with nodsh"
19479
19480         test_fake_rw write
19481 }
19482 run_test 399a "fake write should not be slower than normal write"
19483
19484 test_399b() { # LU-8726 for OST fake read
19485         remote_ost_nodsh && skip "remote OST with nodsh"
19486         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
19487                 skip_env "ldiskfs only test"
19488         fi
19489
19490         test_fake_rw read
19491 }
19492 run_test 399b "fake read should not be slower than normal read"
19493
19494 test_400a() { # LU-1606, was conf-sanity test_74
19495         if ! which $CC > /dev/null 2>&1; then
19496                 skip_env "$CC is not installed"
19497         fi
19498
19499         local extra_flags=''
19500         local out=$TMP/$tfile
19501         local prefix=/usr/include/lustre
19502         local prog
19503
19504         if ! [[ -d $prefix ]]; then
19505                 # Assume we're running in tree and fixup the include path.
19506                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
19507                 extra_flags+=" -L$LUSTRE/utils/.lib"
19508         fi
19509
19510         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
19511                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
19512                         error "client api broken"
19513         done
19514         rm -f $out
19515 }
19516 run_test 400a "Lustre client api program can compile and link"
19517
19518 test_400b() { # LU-1606, LU-5011
19519         local header
19520         local out=$TMP/$tfile
19521         local prefix=/usr/include/linux/lustre
19522
19523         # We use a hard coded prefix so that this test will not fail
19524         # when run in tree. There are headers in lustre/include/lustre/
19525         # that are not packaged (like lustre_idl.h) and have more
19526         # complicated include dependencies (like config.h and lnet/types.h).
19527         # Since this test about correct packaging we just skip them when
19528         # they don't exist (see below) rather than try to fixup cppflags.
19529
19530         if ! which $CC > /dev/null 2>&1; then
19531                 skip_env "$CC is not installed"
19532         fi
19533
19534         for header in $prefix/*.h; do
19535                 if ! [[ -f "$header" ]]; then
19536                         continue
19537                 fi
19538
19539                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
19540                         continue # lustre_ioctl.h is internal header
19541                 fi
19542
19543                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
19544                         error "cannot compile '$header'"
19545         done
19546         rm -f $out
19547 }
19548 run_test 400b "packaged headers can be compiled"
19549
19550 test_401a() { #LU-7437
19551         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
19552         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
19553
19554         #count the number of parameters by "list_param -R"
19555         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
19556         #count the number of parameters by listing proc files
19557         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
19558         echo "proc_dirs='$proc_dirs'"
19559         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
19560         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
19561                       sort -u | wc -l)
19562
19563         [ $params -eq $procs ] ||
19564                 error "found $params parameters vs. $procs proc files"
19565
19566         # test the list_param -D option only returns directories
19567         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
19568         #count the number of parameters by listing proc directories
19569         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
19570                 sort -u | wc -l)
19571
19572         [ $params -eq $procs ] ||
19573                 error "found $params parameters vs. $procs proc files"
19574 }
19575 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
19576
19577 test_401b() {
19578         local save=$($LCTL get_param -n jobid_var)
19579         local tmp=testing
19580
19581         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
19582                 error "no error returned when setting bad parameters"
19583
19584         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
19585         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
19586
19587         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
19588         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
19589         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
19590 }
19591 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
19592
19593 test_401c() {
19594         local jobid_var_old=$($LCTL get_param -n jobid_var)
19595         local jobid_var_new
19596
19597         $LCTL set_param jobid_var= &&
19598                 error "no error returned for 'set_param a='"
19599
19600         jobid_var_new=$($LCTL get_param -n jobid_var)
19601         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19602                 error "jobid_var was changed by setting without value"
19603
19604         $LCTL set_param jobid_var &&
19605                 error "no error returned for 'set_param a'"
19606
19607         jobid_var_new=$($LCTL get_param -n jobid_var)
19608         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19609                 error "jobid_var was changed by setting without value"
19610 }
19611 run_test 401c "Verify 'lctl set_param' without value fails in either format."
19612
19613 test_401d() {
19614         local jobid_var_old=$($LCTL get_param -n jobid_var)
19615         local jobid_var_new
19616         local new_value="foo=bar"
19617
19618         $LCTL set_param jobid_var=$new_value ||
19619                 error "'set_param a=b' did not accept a value containing '='"
19620
19621         jobid_var_new=$($LCTL get_param -n jobid_var)
19622         [[ "$jobid_var_new" == "$new_value" ]] ||
19623                 error "'set_param a=b' failed on a value containing '='"
19624
19625         # Reset the jobid_var to test the other format
19626         $LCTL set_param jobid_var=$jobid_var_old
19627         jobid_var_new=$($LCTL get_param -n jobid_var)
19628         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19629                 error "failed to reset jobid_var"
19630
19631         $LCTL set_param jobid_var $new_value ||
19632                 error "'set_param a b' did not accept a value containing '='"
19633
19634         jobid_var_new=$($LCTL get_param -n jobid_var)
19635         [[ "$jobid_var_new" == "$new_value" ]] ||
19636                 error "'set_param a b' failed on a value containing '='"
19637
19638         $LCTL set_param jobid_var $jobid_var_old
19639         jobid_var_new=$($LCTL get_param -n jobid_var)
19640         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19641                 error "failed to reset jobid_var"
19642 }
19643 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
19644
19645 test_402() {
19646         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
19647         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
19648                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
19649         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
19650                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
19651                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
19652         remote_mds_nodsh && skip "remote MDS with nodsh"
19653
19654         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
19655 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
19656         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
19657         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
19658                 echo "Touch failed - OK"
19659 }
19660 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
19661
19662 test_403() {
19663         local file1=$DIR/$tfile.1
19664         local file2=$DIR/$tfile.2
19665         local tfile=$TMP/$tfile
19666
19667         rm -f $file1 $file2 $tfile
19668
19669         touch $file1
19670         ln $file1 $file2
19671
19672         # 30 sec OBD_TIMEOUT in ll_getattr()
19673         # right before populating st_nlink
19674         $LCTL set_param fail_loc=0x80001409
19675         stat -c %h $file1 > $tfile &
19676
19677         # create an alias, drop all locks and reclaim the dentry
19678         < $file2
19679         cancel_lru_locks mdc
19680         cancel_lru_locks osc
19681         sysctl -w vm.drop_caches=2
19682
19683         wait
19684
19685         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
19686
19687         rm -f $tfile $file1 $file2
19688 }
19689 run_test 403 "i_nlink should not drop to zero due to aliasing"
19690
19691 test_404() { # LU-6601
19692         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
19693                 skip "Need server version newer than 2.8.52"
19694         remote_mds_nodsh && skip "remote MDS with nodsh"
19695
19696         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
19697                 awk '/osp .*-osc-MDT/ { print $4}')
19698
19699         local osp
19700         for osp in $mosps; do
19701                 echo "Deactivate: " $osp
19702                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
19703                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19704                         awk -vp=$osp '$4 == p { print $2 }')
19705                 [ $stat = IN ] || {
19706                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19707                         error "deactivate error"
19708                 }
19709                 echo "Activate: " $osp
19710                 do_facet $SINGLEMDS $LCTL --device %$osp activate
19711                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19712                         awk -vp=$osp '$4 == p { print $2 }')
19713                 [ $stat = UP ] || {
19714                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19715                         error "activate error"
19716                 }
19717         done
19718 }
19719 run_test 404 "validate manual {de}activated works properly for OSPs"
19720
19721 test_405() {
19722         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19723         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
19724                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
19725                         skip "Layout swap lock is not supported"
19726
19727         check_swap_layouts_support
19728
19729         test_mkdir $DIR/$tdir
19730         swap_lock_test -d $DIR/$tdir ||
19731                 error "One layout swap locked test failed"
19732 }
19733 run_test 405 "Various layout swap lock tests"
19734
19735 test_406() {
19736         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19737         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19738         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19740         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
19741                 skip "Need MDS version at least 2.8.50"
19742
19743         local def_stripe_size=$($LFS getstripe -S $MOUNT)
19744         local test_pool=$TESTNAME
19745
19746         if ! combined_mgs_mds ; then
19747                 mount_mgs_client
19748         fi
19749         pool_add $test_pool || error "pool_add failed"
19750         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
19751                 error "pool_add_targets failed"
19752
19753         save_layout_restore_at_exit $MOUNT
19754
19755         # parent set default stripe count only, child will stripe from both
19756         # parent and fs default
19757         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
19758                 error "setstripe $MOUNT failed"
19759         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
19760         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
19761         for i in $(seq 10); do
19762                 local f=$DIR/$tdir/$tfile.$i
19763                 touch $f || error "touch failed"
19764                 local count=$($LFS getstripe -c $f)
19765                 [ $count -eq $OSTCOUNT ] ||
19766                         error "$f stripe count $count != $OSTCOUNT"
19767                 local offset=$($LFS getstripe -i $f)
19768                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
19769                 local size=$($LFS getstripe -S $f)
19770                 [ $size -eq $((def_stripe_size * 2)) ] ||
19771                         error "$f stripe size $size != $((def_stripe_size * 2))"
19772                 local pool=$($LFS getstripe -p $f)
19773                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
19774         done
19775
19776         # change fs default striping, delete parent default striping, now child
19777         # will stripe from new fs default striping only
19778         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
19779                 error "change $MOUNT default stripe failed"
19780         $LFS setstripe -c 0 $DIR/$tdir ||
19781                 error "delete $tdir default stripe failed"
19782         for i in $(seq 11 20); do
19783                 local f=$DIR/$tdir/$tfile.$i
19784                 touch $f || error "touch $f failed"
19785                 local count=$($LFS getstripe -c $f)
19786                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
19787                 local offset=$($LFS getstripe -i $f)
19788                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
19789                 local size=$($LFS getstripe -S $f)
19790                 [ $size -eq $def_stripe_size ] ||
19791                         error "$f stripe size $size != $def_stripe_size"
19792                 local pool=$($LFS getstripe -p $f)
19793                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
19794         done
19795
19796         unlinkmany $DIR/$tdir/$tfile. 1 20
19797
19798         local f=$DIR/$tdir/$tfile
19799         pool_remove_all_targets $test_pool $f
19800         pool_remove $test_pool $f
19801
19802         if ! combined_mgs_mds ; then
19803                 umount_mgs_client
19804         fi
19805 }
19806 run_test 406 "DNE support fs default striping"
19807
19808 test_407() {
19809         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19810         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19811                 skip "Need MDS version at least 2.8.55"
19812         remote_mds_nodsh && skip "remote MDS with nodsh"
19813
19814         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
19815                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
19816         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
19817                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
19818         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
19819
19820         #define OBD_FAIL_DT_TXN_STOP    0x2019
19821         for idx in $(seq $MDSCOUNT); do
19822                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
19823         done
19824         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
19825         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
19826                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
19827         true
19828 }
19829 run_test 407 "transaction fail should cause operation fail"
19830
19831 test_408() {
19832         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
19833
19834         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
19835         lctl set_param fail_loc=0x8000040a
19836         # let ll_prepare_partial_page() fail
19837         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
19838
19839         rm -f $DIR/$tfile
19840
19841         # create at least 100 unused inodes so that
19842         # shrink_icache_memory(0) should not return 0
19843         touch $DIR/$tfile-{0..100}
19844         rm -f $DIR/$tfile-{0..100}
19845         sync
19846
19847         echo 2 > /proc/sys/vm/drop_caches
19848 }
19849 run_test 408 "drop_caches should not hang due to page leaks"
19850
19851 test_409()
19852 {
19853         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19854
19855         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
19856         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
19857         touch $DIR/$tdir/guard || error "(2) Fail to create"
19858
19859         local PREFIX=$(str_repeat 'A' 128)
19860         echo "Create 1K hard links start at $(date)"
19861         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19862                 error "(3) Fail to hard link"
19863
19864         echo "Links count should be right although linkEA overflow"
19865         stat $DIR/$tdir/guard || error "(4) Fail to stat"
19866         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
19867         [ $linkcount -eq 1001 ] ||
19868                 error "(5) Unexpected hard links count: $linkcount"
19869
19870         echo "List all links start at $(date)"
19871         ls -l $DIR/$tdir/foo > /dev/null ||
19872                 error "(6) Fail to list $DIR/$tdir/foo"
19873
19874         echo "Unlink hard links start at $(date)"
19875         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19876                 error "(7) Fail to unlink"
19877         echo "Unlink hard links finished at $(date)"
19878 }
19879 run_test 409 "Large amount of cross-MDTs hard links on the same file"
19880
19881 test_410()
19882 {
19883         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
19884                 skip "Need client version at least 2.9.59"
19885
19886         # Create a file, and stat it from the kernel
19887         local testfile=$DIR/$tfile
19888         touch $testfile
19889
19890         local run_id=$RANDOM
19891         local my_ino=$(stat --format "%i" $testfile)
19892
19893         # Try to insert the module. This will always fail as the
19894         # module is designed to not be inserted.
19895         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
19896             &> /dev/null
19897
19898         # Anything but success is a test failure
19899         dmesg | grep -q \
19900             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
19901             error "no inode match"
19902 }
19903 run_test 410 "Test inode number returned from kernel thread"
19904
19905 cleanup_test411_cgroup() {
19906         trap 0
19907         rmdir "$1"
19908 }
19909
19910 test_411() {
19911         local cg_basedir=/sys/fs/cgroup/memory
19912         # LU-9966
19913         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
19914                 skip "no setup for cgroup"
19915
19916         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
19917                 error "test file creation failed"
19918         cancel_lru_locks osc
19919
19920         # Create a very small memory cgroup to force a slab allocation error
19921         local cgdir=$cg_basedir/osc_slab_alloc
19922         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
19923         trap "cleanup_test411_cgroup $cgdir" EXIT
19924         echo 2M > $cgdir/memory.kmem.limit_in_bytes
19925         echo 1M > $cgdir/memory.limit_in_bytes
19926
19927         # Should not LBUG, just be killed by oom-killer
19928         # dd will return 0 even allocation failure in some environment.
19929         # So don't check return value
19930         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
19931         cleanup_test411_cgroup $cgdir
19932
19933         return 0
19934 }
19935 run_test 411 "Slab allocation error with cgroup does not LBUG"
19936
19937 test_412() {
19938         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19939         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19940                 skip "Need server version at least 2.10.55"
19941         fi
19942
19943         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
19944                 error "mkdir failed"
19945         $LFS getdirstripe $DIR/$tdir
19946         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19947         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
19948                 error "expect $((MDSCOUT - 1)) get $stripe_index"
19949         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
19950         [ $stripe_count -eq 2 ] ||
19951                 error "expect 2 get $stripe_count"
19952 }
19953 run_test 412 "mkdir on specific MDTs"
19954
19955 test_413() {
19956         [ $MDSCOUNT -lt 2 ] &&
19957                 skip "We need at least 2 MDTs for this test"
19958
19959         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19960                 skip "Need server version at least 2.10.55"
19961         fi
19962
19963         mkdir $DIR/$tdir || error "mkdir failed"
19964
19965         # find MDT that is the most full
19966         local max=$($LFS df | grep MDT |
19967                 awk 'BEGIN { a=0 }
19968                         { sub("%", "", $5)
19969                           if (0+$5 >= a)
19970                           {
19971                                 a = $5
19972                                 b = $6
19973                           }
19974                         }
19975                      END { split(b, c, ":")
19976                            sub("]", "", c[2])
19977                            print c[2]
19978                          }')
19979
19980         for i in $(seq $((MDSCOUNT - 1))); do
19981                 $LFS mkdir -c $i $DIR/$tdir/d$i ||
19982                         error "mkdir d$i failed"
19983                 $LFS getdirstripe $DIR/$tdir/d$i
19984                 local stripe_index=$($LFS getdirstripe -i $DIR/$tdir/d$i)
19985                 [ $stripe_index -ne $max ] ||
19986                         error "don't expect $max"
19987         done
19988 }
19989 run_test 413 "mkdir on less full MDTs"
19990
19991 test_414() {
19992 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
19993         $LCTL set_param fail_loc=0x80000521
19994         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
19995         rm -f $DIR/$tfile
19996 }
19997 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
19998
19999 test_415() {
20000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20001         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
20002                 skip "Need server version at least 2.11.52"
20003
20004         # LU-11102
20005         local total
20006         local setattr_pid
20007         local start_time
20008         local end_time
20009         local duration
20010
20011         total=500
20012         # this test may be slow on ZFS
20013         [ "$mds1_FSTYPE" == "zfs" ] && total=100
20014
20015         # though this test is designed for striped directory, let's test normal
20016         # directory too since lock is always saved as CoS lock.
20017         test_mkdir $DIR/$tdir || error "mkdir $tdir"
20018         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
20019
20020         (
20021                 while true; do
20022                         touch $DIR/$tdir
20023                 done
20024         ) &
20025         setattr_pid=$!
20026
20027         start_time=$(date +%s)
20028         for i in $(seq $total); do
20029                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
20030                         > /dev/null
20031         done
20032         end_time=$(date +%s)
20033         duration=$((end_time - start_time))
20034
20035         kill -9 $setattr_pid
20036
20037         echo "rename $total files took $duration sec"
20038         [ $duration -lt 100 ] || error "rename took $duration sec"
20039 }
20040 run_test 415 "lock revoke is not missing"
20041
20042 test_416() {
20043         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
20044                 skip "Need server version at least 2.11.55"
20045
20046         # define OBD_FAIL_OSD_TXN_START    0x19a
20047         do_facet mds1 lctl set_param fail_loc=0x19a
20048
20049         lfs mkdir -c $MDSCOUNT $DIR/$tdir
20050
20051         true
20052 }
20053 run_test 416 "transaction start failure won't cause system hung"
20054
20055 cleanup_417() {
20056         trap 0
20057         do_nodes $(comma_list $(mdts_nodes)) \
20058                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
20059         do_nodes $(comma_list $(mdts_nodes)) \
20060                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
20061         do_nodes $(comma_list $(mdts_nodes)) \
20062                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
20063 }
20064
20065 test_417() {
20066         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20067         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
20068                 skip "Need MDS version at least 2.11.56"
20069
20070         trap cleanup_417 RETURN EXIT
20071
20072         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
20073         do_nodes $(comma_list $(mdts_nodes)) \
20074                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
20075         $LFS migrate -m 0 $DIR/$tdir.1 &&
20076                 error "migrate dir $tdir.1 should fail"
20077
20078         do_nodes $(comma_list $(mdts_nodes)) \
20079                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
20080         $LFS mkdir -i 1 $DIR/$tdir.2 &&
20081                 error "create remote dir $tdir.2 should fail"
20082
20083         do_nodes $(comma_list $(mdts_nodes)) \
20084                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
20085         $LFS mkdir -c 2 $DIR/$tdir.3 &&
20086                 error "create striped dir $tdir.3 should fail"
20087         true
20088 }
20089 run_test 417 "disable remote dir, striped dir and dir migration"
20090
20091 # Checks that the outputs of df [-i] and lfs df [-i] match
20092 #
20093 # usage: check_lfs_df <blocks | inodes> <mountpoint>
20094 check_lfs_df() {
20095         local dir=$2
20096         local inodes
20097         local df_out
20098         local lfs_df_out
20099         local count
20100         local passed=false
20101
20102         # blocks or inodes
20103         [ "$1" == "blocks" ] && inodes= || inodes="-i"
20104
20105         for count in {1..100}; do
20106                 cancel_lru_locks
20107                 sync; sleep 0.2
20108
20109                 # read the lines of interest
20110                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
20111                         error "df $inodes $dir | tail -n +2 failed"
20112                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
20113                         error "lfs df $inodes $dir | grep summary: failed"
20114
20115                 # skip first substrings of each output as they are different
20116                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
20117                 # compare the two outputs
20118                 passed=true
20119                 for i in {1..5}; do
20120                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
20121                 done
20122                 $passed && break
20123         done
20124
20125         if ! $passed; then
20126                 df -P $inodes $dir
20127                 echo
20128                 lfs df $inodes $dir
20129                 error "df and lfs df $1 output mismatch: "      \
20130                       "df ${inodes}: ${df_out[*]}, "            \
20131                       "lfs df ${inodes}: ${lfs_df_out[*]}"
20132         fi
20133 }
20134
20135 test_418() {
20136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20137
20138         local dir=$DIR/$tdir
20139         local numfiles=$((RANDOM % 4096 + 2))
20140         local numblocks=$((RANDOM % 256 + 1))
20141
20142         wait_delete_completed
20143         test_mkdir $dir
20144
20145         # check block output
20146         check_lfs_df blocks $dir
20147         # check inode output
20148         check_lfs_df inodes $dir
20149
20150         # create a single file and retest
20151         echo "Creating a single file and testing"
20152         createmany -o $dir/$tfile- 1 &>/dev/null ||
20153                 error "creating 1 file in $dir failed"
20154         check_lfs_df blocks $dir
20155         check_lfs_df inodes $dir
20156
20157         # create a random number of files
20158         echo "Creating $((numfiles - 1)) files and testing"
20159         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
20160                 error "creating $((numfiles - 1)) files in $dir failed"
20161
20162         # write a random number of blocks to the first test file
20163         echo "Writing $numblocks 4K blocks and testing"
20164         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
20165                 count=$numblocks &>/dev/null ||
20166                 error "dd to $dir/${tfile}-0 failed"
20167
20168         # retest
20169         check_lfs_df blocks $dir
20170         check_lfs_df inodes $dir
20171
20172         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
20173                 error "unlinking $numfiles files in $dir failed"
20174 }
20175 run_test 418 "df and lfs df outputs match"
20176
20177 test_419()
20178 {
20179         local dir=$DIR/$tdir
20180
20181         mkdir -p $dir
20182         touch $dir/file
20183
20184         cancel_lru_locks mdc
20185
20186         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
20187         $LCTL set_param fail_loc=0x1410
20188         cat $dir/file
20189         $LCTL set_param fail_loc=0
20190         rm -rf $dir
20191 }
20192 run_test 419 "Verify open file by name doesn't crash kernel"
20193
20194 test_420()
20195 {
20196         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
20197                 skip "Need MDS version at least 2.12.53"
20198
20199         local SAVE_UMASK=$(umask)
20200         local dir=$DIR/$tdir
20201         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
20202
20203         mkdir -p $dir
20204         umask 0000
20205         mkdir -m03777 $dir/testdir
20206         ls -dn $dir/testdir
20207         local dirperms=$(ls -dn $dir/testdir | awk '{print $1}')
20208         [ $dirperms == "drwxrwsrwt" ] ||
20209                 error "incorrect perms on $dir/testdir"
20210
20211         $PDSH ${uname}@localhost "PATH=$LUSTRE/tests:\$PATH; \
20212                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
20213         ls -n $dir/testdir/testfile
20214         local fileperms=$(ls -n $dir/testdir/testfile | awk '{print $1}')
20215         [ $fileperms == "-rwxr-xr-x" ] ||
20216                 error "incorrect perms on $dir/testdir/testfile"
20217
20218         umask $SAVE_UMASK
20219 }
20220 run_test 420 "clear SGID bit on non-directories for non-members"
20221
20222 prep_801() {
20223         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
20224         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
20225                 skip "Need server version at least 2.9.55"
20226
20227         start_full_debug_logging
20228 }
20229
20230 post_801() {
20231         stop_full_debug_logging
20232 }
20233
20234 barrier_stat() {
20235         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
20236                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
20237                            awk '/The barrier for/ { print $7 }')
20238                 echo $st
20239         else
20240                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
20241                 echo \'$st\'
20242         fi
20243 }
20244
20245 barrier_expired() {
20246         local expired
20247
20248         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
20249                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
20250                           awk '/will be expired/ { print $7 }')
20251         else
20252                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
20253         fi
20254
20255         echo $expired
20256 }
20257
20258 test_801a() {
20259         prep_801
20260
20261         echo "Start barrier_freeze at: $(date)"
20262         #define OBD_FAIL_BARRIER_DELAY          0x2202
20263         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
20264         do_facet mgs $LCTL barrier_freeze $FSNAME 10 &
20265
20266         sleep 2
20267         local b_status=$(barrier_stat)
20268         echo "Got barrier status at: $(date)"
20269         [ "$b_status" = "'freezing_p1'" ] ||
20270                 error "(1) unexpected barrier status $b_status"
20271
20272         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
20273         wait
20274         b_status=$(barrier_stat)
20275         [ "$b_status" = "'frozen'" ] ||
20276                 error "(2) unexpected barrier status $b_status"
20277
20278         local expired=$(barrier_expired)
20279         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
20280         sleep $((expired + 3))
20281
20282         b_status=$(barrier_stat)
20283         [ "$b_status" = "'expired'" ] ||
20284                 error "(3) unexpected barrier status $b_status"
20285
20286         do_facet mgs $LCTL barrier_freeze $FSNAME 10 ||
20287                 error "(4) fail to freeze barrier"
20288
20289         b_status=$(barrier_stat)
20290         [ "$b_status" = "'frozen'" ] ||
20291                 error "(5) unexpected barrier status $b_status"
20292
20293         echo "Start barrier_thaw at: $(date)"
20294         #define OBD_FAIL_BARRIER_DELAY          0x2202
20295         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
20296         do_facet mgs $LCTL barrier_thaw $FSNAME &
20297
20298         sleep 2
20299         b_status=$(barrier_stat)
20300         echo "Got barrier status at: $(date)"
20301         [ "$b_status" = "'thawing'" ] ||
20302                 error "(6) unexpected barrier status $b_status"
20303
20304         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
20305         wait
20306         b_status=$(barrier_stat)
20307         [ "$b_status" = "'thawed'" ] ||
20308                 error "(7) unexpected barrier status $b_status"
20309
20310         #define OBD_FAIL_BARRIER_FAILURE        0x2203
20311         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
20312         do_facet mgs $LCTL barrier_freeze $FSNAME
20313
20314         b_status=$(barrier_stat)
20315         [ "$b_status" = "'failed'" ] ||
20316                 error "(8) unexpected barrier status $b_status"
20317
20318         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20319         do_facet mgs $LCTL barrier_thaw $FSNAME
20320
20321         post_801
20322 }
20323 run_test 801a "write barrier user interfaces and stat machine"
20324
20325 test_801b() {
20326         prep_801
20327
20328         mkdir $DIR/$tdir || error "(1) fail to mkdir"
20329         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
20330         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
20331         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
20332         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
20333
20334         cancel_lru_locks mdc
20335
20336         # 180 seconds should be long enough
20337         do_facet mgs $LCTL barrier_freeze $FSNAME 180
20338
20339         local b_status=$(barrier_stat)
20340         [ "$b_status" = "'frozen'" ] ||
20341                 error "(6) unexpected barrier status $b_status"
20342
20343         mkdir $DIR/$tdir/d0/d10 &
20344         mkdir_pid=$!
20345
20346         touch $DIR/$tdir/d1/f13 &
20347         touch_pid=$!
20348
20349         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
20350         ln_pid=$!
20351
20352         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
20353         mv_pid=$!
20354
20355         rm -f $DIR/$tdir/d4/f12 &
20356         rm_pid=$!
20357
20358         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
20359
20360         # To guarantee taht the 'stat' is not blocked
20361         b_status=$(barrier_stat)
20362         [ "$b_status" = "'frozen'" ] ||
20363                 error "(8) unexpected barrier status $b_status"
20364
20365         # let above commands to run at background
20366         sleep 5
20367
20368         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
20369         ps -p $touch_pid || error "(10) touch should be blocked"
20370         ps -p $ln_pid || error "(11) link should be blocked"
20371         ps -p $mv_pid || error "(12) rename should be blocked"
20372         ps -p $rm_pid || error "(13) unlink should be blocked"
20373
20374         b_status=$(barrier_stat)
20375         [ "$b_status" = "'frozen'" ] ||
20376                 error "(14) unexpected barrier status $b_status"
20377
20378         do_facet mgs $LCTL barrier_thaw $FSNAME
20379         b_status=$(barrier_stat)
20380         [ "$b_status" = "'thawed'" ] ||
20381                 error "(15) unexpected barrier status $b_status"
20382
20383         wait $mkdir_pid || error "(16) mkdir should succeed"
20384         wait $touch_pid || error "(17) touch should succeed"
20385         wait $ln_pid || error "(18) link should succeed"
20386         wait $mv_pid || error "(19) rename should succeed"
20387         wait $rm_pid || error "(20) unlink should succeed"
20388
20389         post_801
20390 }
20391 run_test 801b "modification will be blocked by write barrier"
20392
20393 test_801c() {
20394         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20395
20396         prep_801
20397
20398         stop mds2 || error "(1) Fail to stop mds2"
20399
20400         do_facet mgs $LCTL barrier_freeze $FSNAME 30
20401
20402         local b_status=$(barrier_stat)
20403         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
20404                 do_facet mgs $LCTL barrier_thaw $FSNAME
20405                 error "(2) unexpected barrier status $b_status"
20406         }
20407
20408         do_facet mgs $LCTL barrier_rescan $FSNAME ||
20409                 error "(3) Fail to rescan barrier bitmap"
20410
20411         do_facet mgs $LCTL barrier_freeze $FSNAME 10
20412
20413         b_status=$(barrier_stat)
20414         [ "$b_status" = "'frozen'" ] ||
20415                 error "(4) unexpected barrier status $b_status"
20416
20417         do_facet mgs $LCTL barrier_thaw $FSNAME
20418         b_status=$(barrier_stat)
20419         [ "$b_status" = "'thawed'" ] ||
20420                 error "(5) unexpected barrier status $b_status"
20421
20422         local devname=$(mdsdevname 2)
20423
20424         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
20425
20426         do_facet mgs $LCTL barrier_rescan $FSNAME ||
20427                 error "(7) Fail to rescan barrier bitmap"
20428
20429         post_801
20430 }
20431 run_test 801c "rescan barrier bitmap"
20432
20433 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
20434 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
20435 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
20436
20437 cleanup_802a() {
20438         trap 0
20439
20440         stopall
20441         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
20442         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
20443         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
20444         setupall
20445 }
20446
20447 test_802a() {
20448
20449         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
20450         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
20451                 skip "Need server version at least 2.9.55"
20452
20453         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
20454
20455         mkdir $DIR/$tdir || error "(1) fail to mkdir"
20456
20457         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
20458                 error "(2) Fail to copy"
20459
20460         trap cleanup_802a EXIT
20461
20462         # sync by force before remount as readonly
20463         sync; sync_all_data; sleep 3; sync_all_data
20464
20465         stopall
20466
20467         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
20468         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
20469         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
20470
20471         echo "Mount the server as read only"
20472         setupall server_only || error "(3) Fail to start servers"
20473
20474         echo "Mount client without ro should fail"
20475         mount_client $MOUNT &&
20476                 error "(4) Mount client without 'ro' should fail"
20477
20478         echo "Mount client with ro should succeed"
20479         mount_client $MOUNT ro ||
20480                 error "(5) Mount client with 'ro' should succeed"
20481
20482         echo "Modify should be refused"
20483         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
20484
20485         echo "Read should be allowed"
20486         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
20487                 error "(7) Read should succeed under ro mode"
20488
20489         cleanup_802a
20490 }
20491 run_test 802a "simulate readonly device"
20492
20493 test_802b() {
20494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20495         remote_mds_nodsh && skip "remote MDS with nodsh"
20496
20497         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
20498                 skip "readonly option not available"
20499
20500         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
20501
20502         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
20503                 error "(2) Fail to copy"
20504
20505         # write back all cached data before setting MDT to readonly
20506         cancel_lru_locks
20507         sync_all_data
20508
20509         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
20510         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
20511
20512         echo "Modify should be refused"
20513         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
20514
20515         echo "Read should be allowed"
20516         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
20517                 error "(7) Read should succeed under ro mode"
20518
20519         # disable readonly
20520         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
20521 }
20522 run_test 802b "be able to set MDTs to readonly"
20523
20524 test_803() {
20525         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20526         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
20527                 skip "MDS needs to be newer than 2.10.54"
20528
20529         mkdir -p $DIR/$tdir
20530         # Create some objects on all MDTs to trigger related logs objects
20531         for idx in $(seq $MDSCOUNT); do
20532                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
20533                         $DIR/$tdir/dir${idx} ||
20534                         error "Fail to create $DIR/$tdir/dir${idx}"
20535         done
20536
20537         sync; sleep 3
20538         wait_delete_completed # ensure old test cleanups are finished
20539         echo "before create:"
20540         $LFS df -i $MOUNT
20541         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20542
20543         for i in {1..10}; do
20544                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
20545                         error "Fail to create $DIR/$tdir/foo$i"
20546         done
20547
20548         sync; sleep 3
20549         echo "after create:"
20550         $LFS df -i $MOUNT
20551         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20552
20553         # allow for an llog to be cleaned up during the test
20554         [ $after_used -ge $((before_used + 10 - 1)) ] ||
20555                 error "before ($before_used) + 10 > after ($after_used)"
20556
20557         for i in {1..10}; do
20558                 rm -rf $DIR/$tdir/foo$i ||
20559                         error "Fail to remove $DIR/$tdir/foo$i"
20560         done
20561
20562         sleep 3 # avoid MDT return cached statfs
20563         wait_delete_completed
20564         echo "after unlink:"
20565         $LFS df -i $MOUNT
20566         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20567
20568         # allow for an llog to be created during the test
20569         [ $after_used -le $((before_used + 1)) ] ||
20570                 error "after ($after_used) > before ($before_used) + 1"
20571 }
20572 run_test 803 "verify agent object for remote object"
20573
20574 test_804() {
20575         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20576         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
20577                 skip "MDS needs to be newer than 2.10.54"
20578         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20579
20580         mkdir -p $DIR/$tdir
20581         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
20582                 error "Fail to create $DIR/$tdir/dir0"
20583
20584         local fid=$($LFS path2fid $DIR/$tdir/dir0)
20585         local dev=$(mdsdevname 2)
20586
20587         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20588                 grep ${fid} || error "NOT found agent entry for dir0"
20589
20590         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
20591                 error "Fail to create $DIR/$tdir/dir1"
20592
20593         touch $DIR/$tdir/dir1/foo0 ||
20594                 error "Fail to create $DIR/$tdir/dir1/foo0"
20595         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
20596         local rc=0
20597
20598         for idx in $(seq $MDSCOUNT); do
20599                 dev=$(mdsdevname $idx)
20600                 do_facet mds${idx} \
20601                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20602                         grep ${fid} && rc=$idx
20603         done
20604
20605         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
20606                 error "Fail to rename foo0 to foo1"
20607         if [ $rc -eq 0 ]; then
20608                 for idx in $(seq $MDSCOUNT); do
20609                         dev=$(mdsdevname $idx)
20610                         do_facet mds${idx} \
20611                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20612                         grep ${fid} && rc=$idx
20613                 done
20614         fi
20615
20616         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
20617                 error "Fail to rename foo1 to foo2"
20618         if [ $rc -eq 0 ]; then
20619                 for idx in $(seq $MDSCOUNT); do
20620                         dev=$(mdsdevname $idx)
20621                         do_facet mds${idx} \
20622                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20623                         grep ${fid} && rc=$idx
20624                 done
20625         fi
20626
20627         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
20628
20629         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
20630                 error "Fail to link to $DIR/$tdir/dir1/foo2"
20631         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
20632                 error "Fail to rename foo2 to foo0"
20633         unlink $DIR/$tdir/dir1/foo0 ||
20634                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
20635         rm -rf $DIR/$tdir/dir0 ||
20636                 error "Fail to rm $DIR/$tdir/dir0"
20637
20638         for idx in $(seq $MDSCOUNT); do
20639                 dev=$(mdsdevname $idx)
20640                 rc=0
20641
20642                 stop mds${idx}
20643                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
20644                         rc=$?
20645                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
20646                         error "mount mds$idx failed"
20647                 df $MOUNT > /dev/null 2>&1
20648
20649                 # e2fsck should not return error
20650                 [ $rc -eq 0 ] ||
20651                         error "e2fsck detected error on MDT${idx}: rc=$rc"
20652         done
20653 }
20654 run_test 804 "verify agent entry for remote entry"
20655
20656 cleanup_805() {
20657         do_facet $SINGLEMDS zfs set quota=$old $fsset
20658         unlinkmany $DIR/$tdir/f- 1000000
20659         trap 0
20660 }
20661
20662 test_805() {
20663         local zfs_version=$(do_node $SINGLEMDS cat /sys/module/zfs/version)
20664         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
20665         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
20666                 skip "netfree not implemented before 0.7"
20667         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
20668                 skip "Need MDS version at least 2.10.57"
20669
20670         local fsset
20671         local freekb
20672         local usedkb
20673         local old
20674         local quota
20675         local pref="osd-zfs.lustre-MDT0000."
20676
20677         # limit available space on MDS dataset to meet nospace issue
20678         # quickly. then ZFS 0.7.2 can use reserved space if asked
20679         # properly (using netfree flag in osd_declare_destroy()
20680         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
20681         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
20682                 gawk '{print $3}')
20683         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
20684         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
20685         let "usedkb=usedkb-freekb"
20686         let "freekb=freekb/2"
20687         if let "freekb > 5000"; then
20688                 let "freekb=5000"
20689         fi
20690         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
20691         trap cleanup_805 EXIT
20692         mkdir $DIR/$tdir
20693         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
20694         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
20695         rm -rf $DIR/$tdir || error "not able to remove"
20696         do_facet $SINGLEMDS zfs set quota=$old $fsset
20697         trap 0
20698 }
20699 run_test 805 "ZFS can remove from full fs"
20700
20701 # Size-on-MDS test
20702 check_lsom_data()
20703 {
20704         local file=$1
20705         local size=$($LFS getsom -s $file)
20706         local expect=$(stat -c %s $file)
20707
20708         [[ $size == $expect ]] ||
20709                 error "$file expected size: $expect, got: $size"
20710
20711         local blocks=$($LFS getsom -b $file)
20712         expect=$(stat -c %b $file)
20713         [[ $blocks == $expect ]] ||
20714                 error "$file expected blocks: $expect, got: $blocks"
20715 }
20716
20717 check_lsom_size()
20718 {
20719         local size=$($LFS getsom -s $1)
20720         local expect=$2
20721
20722         [[ $size == $expect ]] ||
20723                 error "$file expected size: $expect, got: $size"
20724 }
20725
20726 test_806() {
20727         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20728                 skip "Need MDS version at least 2.11.52"
20729
20730         local bs=1048576
20731
20732         touch $DIR/$tfile || error "touch $tfile failed"
20733
20734         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20735         save_lustre_params client "llite.*.xattr_cache" > $save
20736         lctl set_param llite.*.xattr_cache=0
20737         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20738
20739         # single-threaded write
20740         echo "Test SOM for single-threaded write"
20741         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
20742                 error "write $tfile failed"
20743         check_lsom_size $DIR/$tfile $bs
20744
20745         local num=32
20746         local size=$(($num * $bs))
20747         local offset=0
20748         local i
20749
20750         echo "Test SOM for single client multi-threaded($num) write"
20751         $TRUNCATE $DIR/$tfile 0
20752         for ((i = 0; i < $num; i++)); do
20753                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20754                 local pids[$i]=$!
20755                 offset=$((offset + $bs))
20756         done
20757         for (( i=0; i < $num; i++ )); do
20758                 wait ${pids[$i]}
20759         done
20760         check_lsom_size $DIR/$tfile $size
20761
20762         $TRUNCATE $DIR/$tfile 0
20763         for ((i = 0; i < $num; i++)); do
20764                 offset=$((offset - $bs))
20765                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20766                 local pids[$i]=$!
20767         done
20768         for (( i=0; i < $num; i++ )); do
20769                 wait ${pids[$i]}
20770         done
20771         check_lsom_size $DIR/$tfile $size
20772
20773         # multi-client wirtes
20774         num=$(get_node_count ${CLIENTS//,/ })
20775         size=$(($num * $bs))
20776         offset=0
20777         i=0
20778
20779         echo "Test SOM for multi-client ($num) writes"
20780         $TRUNCATE $DIR/$tfile 0
20781         for client in ${CLIENTS//,/ }; do
20782                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20783                 local pids[$i]=$!
20784                 i=$((i + 1))
20785                 offset=$((offset + $bs))
20786         done
20787         for (( i=0; i < $num; i++ )); do
20788                 wait ${pids[$i]}
20789         done
20790         check_lsom_size $DIR/$tfile $offset
20791
20792         i=0
20793         $TRUNCATE $DIR/$tfile 0
20794         for client in ${CLIENTS//,/ }; do
20795                 offset=$((offset - $bs))
20796                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20797                 local pids[$i]=$!
20798                 i=$((i + 1))
20799         done
20800         for (( i=0; i < $num; i++ )); do
20801                 wait ${pids[$i]}
20802         done
20803         check_lsom_size $DIR/$tfile $size
20804
20805         # verify truncate
20806         echo "Test SOM for truncate"
20807         $TRUNCATE $DIR/$tfile 1048576
20808         check_lsom_size $DIR/$tfile 1048576
20809         $TRUNCATE $DIR/$tfile 1234
20810         check_lsom_size $DIR/$tfile 1234
20811
20812         # verify SOM blocks count
20813         echo "Verify SOM block count"
20814         $TRUNCATE $DIR/$tfile 0
20815         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
20816                 error "failed to write file $tfile"
20817         check_lsom_data $DIR/$tfile
20818 }
20819 run_test 806 "Verify Lazy Size on MDS"
20820
20821 test_807() {
20822         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
20823         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20824                 skip "Need MDS version at least 2.11.52"
20825
20826         # Registration step
20827         changelog_register || error "changelog_register failed"
20828         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
20829         changelog_users $SINGLEMDS | grep -q $cl_user ||
20830                 error "User $cl_user not found in changelog_users"
20831
20832         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20833         save_lustre_params client "llite.*.xattr_cache" > $save
20834         lctl set_param llite.*.xattr_cache=0
20835         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20836
20837         rm -rf $DIR/$tdir || error "rm $tdir failed"
20838         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
20839         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
20840         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
20841         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
20842                 error "truncate $tdir/trunc failed"
20843
20844         local bs=1048576
20845         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
20846                 error "write $tfile failed"
20847
20848         # multi-client wirtes
20849         local num=$(get_node_count ${CLIENTS//,/ })
20850         local offset=0
20851         local i=0
20852
20853         echo "Test SOM for multi-client ($num) writes"
20854         touch $DIR/$tfile || error "touch $tfile failed"
20855         $TRUNCATE $DIR/$tfile 0
20856         for client in ${CLIENTS//,/ }; do
20857                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20858                 local pids[$i]=$!
20859                 i=$((i + 1))
20860                 offset=$((offset + $bs))
20861         done
20862         for (( i=0; i < $num; i++ )); do
20863                 wait ${pids[$i]}
20864         done
20865
20866         sleep 5
20867         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
20868         check_lsom_data $DIR/$tdir/trunc
20869         check_lsom_data $DIR/$tdir/single_dd
20870         check_lsom_data $DIR/$tfile
20871
20872         rm -rf $DIR/$tdir
20873         # Deregistration step
20874         changelog_deregister || error "changelog_deregister failed"
20875 }
20876 run_test 807 "verify LSOM syncing tool"
20877
20878 check_som_nologged()
20879 {
20880         local lines=$($LFS changelog $FSNAME-MDT0000 |
20881                 grep 'x=trusted.som' | wc -l)
20882         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
20883 }
20884
20885 test_808() {
20886         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
20887                 skip "Need MDS version at least 2.11.55"
20888
20889         # Registration step
20890         changelog_register || error "changelog_register failed"
20891
20892         touch $DIR/$tfile || error "touch $tfile failed"
20893         check_som_nologged
20894
20895         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
20896                 error "write $tfile failed"
20897         check_som_nologged
20898
20899         $TRUNCATE $DIR/$tfile 1234
20900         check_som_nologged
20901
20902         $TRUNCATE $DIR/$tfile 1048576
20903         check_som_nologged
20904
20905         # Deregistration step
20906         changelog_deregister || error "changelog_deregister failed"
20907 }
20908 run_test 808 "Check trusted.som xattr not logged in Changelogs"
20909
20910 check_som_nodata()
20911 {
20912         $LFS getsom $1
20913         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
20914 }
20915
20916 test_809() {
20917         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20918                 skip "Need MDS version at least 2.11.56"
20919
20920         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
20921                 error "failed to create DoM-only file $DIR/$tfile"
20922         touch $DIR/$tfile || error "touch $tfile failed"
20923         check_som_nodata $DIR/$tfile
20924
20925         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
20926                 error "write $tfile failed"
20927         check_som_nodata $DIR/$tfile
20928
20929         $TRUNCATE $DIR/$tfile 1234
20930         check_som_nodata $DIR/$tfile
20931
20932         $TRUNCATE $DIR/$tfile 4097
20933         check_som_nodata $DIR/$file
20934 }
20935 run_test 809 "Verify no SOM xattr store for DoM-only files"
20936
20937 test_810() {
20938         local ORIG
20939         local CSUM
20940
20941         # t10 seem to dislike partial pages
20942         lctl set_param osc.*.checksum_type=adler
20943         lctl set_param fail_loc=0x411
20944         dd if=/dev/urandom of=$DIR/$tfile bs=10240 count=2
20945         ORIG=$(md5sum $DIR/$tfile)
20946         lctl set_param ldlm.namespaces.*osc*.lru_size=clear
20947         CSUM=$(md5sum $DIR/$tfile)
20948         set_checksum_type adler
20949         if [ "$ORIG" != "$CSUM" ]; then
20950                 error "$ORIG != $CSUM"
20951         fi
20952 }
20953 run_test 810 "partial page writes on ZFS (LU-11663)"
20954
20955 test_811() {
20956         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
20957                 skip "Need MDS version at least 2.11.56"
20958
20959         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
20960         do_facet mds1 $LCTL set_param fail_loc=0x165
20961         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
20962
20963         stop mds1
20964         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20965
20966         sleep 5
20967         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
20968                 error "MDD orphan cleanup thread not quit"
20969 }
20970 run_test 811 "orphan name stub can be cleaned up in startup"
20971
20972 test_812() {
20973         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
20974                 skip "OST < 2.12.51 doesn't support this fail_loc"
20975         [ "$SHARED_KEY" = true ] &&
20976                 skip "OSC connections never go IDLE with Shared-Keys enabled"
20977
20978         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20979         # ensure ost1 is connected
20980         stat $DIR/$tfile >/dev/null || error "can't stat"
20981         wait_osc_import_state client ost1 FULL
20982         # no locks, no reqs to let the connection idle
20983         cancel_lru_locks osc
20984
20985         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
20986 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
20987         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
20988         wait_osc_import_state client ost1 CONNECTING
20989         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
20990
20991         stat $DIR/$tfile >/dev/null || error "can't stat file"
20992 }
20993 run_test 812 "do not drop reqs generated when imp is going to idle (LU-11951)"
20994
20995 test_813() {
20996         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
20997         [ -z "$file_heat_sav" ] && skip "no file heat support"
20998
20999         local readsample
21000         local writesample
21001         local readbyte
21002         local writebyte
21003         local readsample1
21004         local writesample1
21005         local readbyte1
21006         local writebyte1
21007
21008         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
21009         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
21010
21011         $LCTL set_param -n llite.*.file_heat=1
21012         echo "Turn on file heat"
21013         echo "Period second: $period_second, Decay percentage: $decay_pct"
21014
21015         echo "QQQQ" > $DIR/$tfile
21016         echo "QQQQ" > $DIR/$tfile
21017         echo "QQQQ" > $DIR/$tfile
21018         cat $DIR/$tfile > /dev/null
21019         cat $DIR/$tfile > /dev/null
21020         cat $DIR/$tfile > /dev/null
21021         cat $DIR/$tfile > /dev/null
21022
21023         local out=$($LFS heat_get $DIR/$tfile)
21024
21025         $LFS heat_get $DIR/$tfile
21026         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21027         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21028         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21029         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21030
21031         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
21032         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
21033         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
21034         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
21035
21036         sleep $((period_second + 3))
21037         echo "Sleep $((period_second + 3)) seconds..."
21038         # The recursion formula to calculate the heat of the file f is as
21039         # follow:
21040         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
21041         # Where Hi is the heat value in the period between time points i*I and
21042         # (i+1)*I; Ci is the access count in the period; the symbol P refers
21043         # to the weight of Ci.
21044         out=$($LFS heat_get $DIR/$tfile)
21045         $LFS heat_get $DIR/$tfile
21046         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21047         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21048         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21049         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21050
21051         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
21052                 error "read sample ($readsample) is wrong"
21053         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
21054                 error "write sample ($writesample) is wrong"
21055         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
21056                 error "read bytes ($readbyte) is wrong"
21057         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
21058                 error "write bytes ($writebyte) is wrong"
21059
21060         echo "QQQQ" > $DIR/$tfile
21061         echo "QQQQ" > $DIR/$tfile
21062         echo "QQQQ" > $DIR/$tfile
21063         cat $DIR/$tfile > /dev/null
21064         cat $DIR/$tfile > /dev/null
21065         cat $DIR/$tfile > /dev/null
21066         cat $DIR/$tfile > /dev/null
21067
21068         sleep $((period_second + 3))
21069         echo "Sleep $((period_second + 3)) seconds..."
21070
21071         out=$($LFS heat_get $DIR/$tfile)
21072         $LFS heat_get $DIR/$tfile
21073         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21074         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21075         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21076         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21077
21078         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
21079                 4 * $decay_pct) / 100") -eq 1 ] ||
21080                 error "read sample ($readsample1) is wrong"
21081         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
21082                 3 * $decay_pct) / 100") -eq 1 ] ||
21083                 error "write sample ($writesample1) is wrong"
21084         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
21085                 20 * $decay_pct) / 100") -eq 1 ] ||
21086                 error "read bytes ($readbyte1) is wrong"
21087         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
21088                 15 * $decay_pct) / 100") -eq 1 ] ||
21089                 error "write bytes ($writebyte1) is wrong"
21090
21091         echo "Turn off file heat for the file $DIR/$tfile"
21092         $LFS heat_set -o $DIR/$tfile
21093
21094         echo "QQQQ" > $DIR/$tfile
21095         echo "QQQQ" > $DIR/$tfile
21096         echo "QQQQ" > $DIR/$tfile
21097         cat $DIR/$tfile > /dev/null
21098         cat $DIR/$tfile > /dev/null
21099         cat $DIR/$tfile > /dev/null
21100         cat $DIR/$tfile > /dev/null
21101
21102         out=$($LFS heat_get $DIR/$tfile)
21103         $LFS heat_get $DIR/$tfile
21104         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21105         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21106         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21107         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21108
21109         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
21110         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
21111         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
21112         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
21113
21114         echo "Trun on file heat for the file $DIR/$tfile"
21115         $LFS heat_set -O $DIR/$tfile
21116
21117         echo "QQQQ" > $DIR/$tfile
21118         echo "QQQQ" > $DIR/$tfile
21119         echo "QQQQ" > $DIR/$tfile
21120         cat $DIR/$tfile > /dev/null
21121         cat $DIR/$tfile > /dev/null
21122         cat $DIR/$tfile > /dev/null
21123         cat $DIR/$tfile > /dev/null
21124
21125         out=$($LFS heat_get $DIR/$tfile)
21126         $LFS heat_get $DIR/$tfile
21127         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21128         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21129         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21130         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21131
21132         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
21133         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
21134         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
21135         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
21136
21137         $LFS heat_set -c $DIR/$tfile
21138         $LCTL set_param -n llite.*.file_heat=0
21139         echo "Turn off file heat support for the Lustre filesystem"
21140
21141         echo "QQQQ" > $DIR/$tfile
21142         echo "QQQQ" > $DIR/$tfile
21143         echo "QQQQ" > $DIR/$tfile
21144         cat $DIR/$tfile > /dev/null
21145         cat $DIR/$tfile > /dev/null
21146         cat $DIR/$tfile > /dev/null
21147         cat $DIR/$tfile > /dev/null
21148
21149         out=$($LFS heat_get $DIR/$tfile)
21150         $LFS heat_get $DIR/$tfile
21151         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21152         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21153         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21154         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21155
21156         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
21157         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
21158         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
21159         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
21160
21161         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
21162         rm -f $DIR/$tfile
21163 }
21164 run_test 813 "File heat verfication"
21165
21166 #
21167 # tests that do cleanup/setup should be run at the end
21168 #
21169
21170 test_900() {
21171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21172         local ls
21173
21174         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
21175         $LCTL set_param fail_loc=0x903
21176
21177         cancel_lru_locks MGC
21178
21179         FAIL_ON_ERROR=true cleanup
21180         FAIL_ON_ERROR=true setup
21181 }
21182 run_test 900 "umount should not race with any mgc requeue thread"
21183
21184 complete $SECONDS
21185 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
21186 check_and_cleanup_lustre
21187 if [ "$I_MOUNTED" != "yes" ]; then
21188         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
21189 fi
21190 exit_status