Whamcloud - gitweb
LU-11868 osd: Set max ea size to XATTR_SIZE_MAX
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 # -*- tab-width: 8; indent-tabs-mode: t; -*-
3 #
4 # Run select tests by setting ONLY, or as arguments to the script.
5 # Skip specific tests by setting EXCEPT.
6 #
7 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
8 set -e
9
10 ONLY=${ONLY:-"$*"}
11 # bug number for skipped test: LU-9693 LU-6493 LU-9693
12 ALWAYS_EXCEPT="$SANITY_EXCEPT  42a     42b     42c"
13 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
14
15 # skipped tests: LU-8411 LU-9096 LU-9054 ..
16 ALWAYS_EXCEPT="  407     253     312     $ALWAYS_EXCEPT"
17
18 if $SHARED_KEY; then
19 # bug number for skipped tests: LU-9795 (all below)
20         ALWAYS_EXCEPT="$ALWAYS_EXCEPT   17n     60a     133g    300f"
21 fi
22
23 # Check Grants after these tests
24 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
25
26 # skip the grant tests for ARM until they are fixed
27 if [[ $(uname -m) = aarch64 ]]; then
28         # bug number:    LU-11596 (all below)
29         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
30         # bug number:    LU-11671 LU-11594 LU-11667 LU-11729
31         ALWAYS_EXCEPT+=" 45       103a      317      810"
32 fi
33
34 SRCDIR=$(cd $(dirname $0); echo $PWD)
35 export PATH=$PATH:/sbin
36
37 TMP=${TMP:-/tmp}
38 OSC=${OSC:-"osc"}
39
40 CC=${CC:-cc}
41 CHECKSTAT=${CHECKSTAT:-"checkstat -v"}
42 CREATETEST=${CREATETEST:-createtest}
43 LFS=${LFS:-lfs}
44 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
45 LCTL=${LCTL:-lctl}
46 OPENFILE=${OPENFILE:-openfile}
47 OPENUNLINK=${OPENUNLINK:-openunlink}
48 export MULTIOP=${MULTIOP:-multiop}
49 READS=${READS:-"reads"}
50 MUNLINK=${MUNLINK:-munlink}
51 SOCKETSERVER=${SOCKETSERVER:-socketserver}
52 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
53 MEMHOG=${MEMHOG:-memhog}
54 DIRECTIO=${DIRECTIO:-directio}
55 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
56 DEF_STRIPE_COUNT=-1
57 CHECK_GRANT=${CHECK_GRANT:-"yes"}
58 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
59 export PARALLEL=${PARALLEL:-"no"}
60
61 export NAME=${NAME:-local}
62
63 SAVE_PWD=$PWD
64
65 CLEANUP=${CLEANUP:-:}
66 SETUP=${SETUP:-:}
67 TRACE=${TRACE:-""}
68 LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
69 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
70 . $LUSTRE/tests/test-framework.sh
71 init_test_env $@
72 . ${CONFIG:=$LUSTRE/tests/cfg/${NAME}.sh}
73
74 init_logging
75
76 #                                  5          12          (min)"
77 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 300o"
78
79 if [ "$mds1_FSTYPE" = "zfs" ]; then
80         # bug number for skipped test: LU-1957
81         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  180"
82         #                                               13    (min)"
83         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
84 fi
85
86 # Get the SLES distro version
87 #
88 # Returns a version string that should only be used in comparing
89 # strings returned by version_code()
90 sles_version_code()
91 {
92         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
93
94         # All SuSE Linux versions have one decimal. version_code expects two
95         local sles_version=$version.0
96         version_code $sles_version
97 }
98
99 # Check if we are running on Ubuntu or SLES so we can make decisions on
100 # what tests to run
101 if [ -r /etc/SuSE-release ]; then
102         sles_version=$(sles_version_code)
103         [ $sles_version -lt $(version_code 11.4.0) ] &&
104                 # bug number for skipped test: LU-4341
105                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
106         [ $sles_version -lt $(version_code 12.0.0) ] &&
107                 # bug number for skipped test: LU-3703
108                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
109 elif [ -r /etc/os-release ]; then
110         if grep -qi ubuntu /etc/os-release; then
111                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
112                                                 -e 's/^VERSION=//p' \
113                                                 /etc/os-release |
114                                                 awk '{ print $1 }'))
115
116                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
117                         # bug number for skipped test:
118                         #                LU-10334 LU-10366
119                         ALWAYS_EXCEPT+=" 103a     410"
120                 fi
121         fi
122 fi
123
124 FAIL_ON_ERROR=false
125
126 cleanup() {
127         echo -n "cln.."
128         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
129         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
130 }
131 setup() {
132         echo -n "mnt.."
133         load_modules
134         setupall || exit 10
135         echo "done"
136 }
137
138 check_swap_layouts_support()
139 {
140         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
141                 skip "Does not support layout lock."
142 }
143
144 check_and_setup_lustre
145 DIR=${DIR:-$MOUNT}
146 assert_DIR
147
148 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
149
150 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
151 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
152 rm -rf $DIR/[Rdfs][0-9]*
153
154 # $RUNAS_ID may get set incorrectly somewhere else
155 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
156         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
157
158 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
159
160 build_test_filter
161
162 if [ "${ONLY}" = "MOUNT" ] ; then
163         echo "Lustre is up, please go on"
164         exit
165 fi
166
167 echo "preparing for tests involving mounts"
168 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
169 touch $EXT2_DEV
170 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
171 echo # add a newline after mke2fs.
172
173 umask 077
174
175 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
176 lctl set_param debug=-1 2> /dev/null || true
177 test_0a() {
178         touch $DIR/$tfile
179         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
180         rm $DIR/$tfile
181         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
182 }
183 run_test 0a "touch; rm ====================="
184
185 test_0b() {
186         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
187         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
188 }
189 run_test 0b "chmod 0755 $DIR ============================="
190
191 test_0c() {
192         $LCTL get_param mdc.*.import | grep "state: FULL" ||
193                 error "import not FULL"
194         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
195                 error "bad target"
196 }
197 run_test 0c "check import proc"
198
199 test_0d() { # LU-3397
200         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
201                 skip "proc exports not supported before 2.10.57"
202
203         local mgs_exp="mgs.MGS.exports"
204         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
205         local exp_client_nid
206         local exp_client_version
207         local exp_val
208         local imp_val
209         local temp_imp=$DIR/$tfile.import
210         local temp_exp=$DIR/$tfile.export
211
212         # save mgc import file to $temp_imp
213         $LCTL get_param mgc.*.import | tee $temp_imp
214         # Check if client uuid is found in MGS export
215         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
216                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
217                         $client_uuid ] &&
218                         break;
219         done
220         # save mgs export file to $temp_exp
221         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
222
223         # Compare the value of field "connect_flags"
224         imp_val=$(grep "connect_flags" $temp_imp)
225         exp_val=$(grep "connect_flags" $temp_exp)
226         [ "$exp_val" == "$imp_val" ] ||
227                 error "export flags '$exp_val' != import flags '$imp_val'"
228
229         # Compare the value of client version
230         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
231         exp_val=$(version_code $exp_client_version)
232         imp_val=$CLIENT_VERSION
233         [ "$exp_val" == "$imp_val" ] ||
234                 error "export client version '$exp_val' != '$imp_val'"
235 }
236 run_test 0d "check export proc ============================="
237
238 test_1() {
239         test_mkdir $DIR/$tdir
240         test_mkdir $DIR/$tdir/d2
241         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
242         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
243         rmdir $DIR/$tdir/d2
244         rmdir $DIR/$tdir
245         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
246 }
247 run_test 1 "mkdir; remkdir; rmdir"
248
249 test_2() {
250         test_mkdir $DIR/$tdir
251         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
252         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
253         rm -r $DIR/$tdir
254         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
255 }
256 run_test 2 "mkdir; touch; rmdir; check file"
257
258 test_3() {
259         test_mkdir $DIR/$tdir
260         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
261         touch $DIR/$tdir/$tfile
262         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
263         rm -r $DIR/$tdir
264         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
265 }
266 run_test 3 "mkdir; touch; rmdir; check dir"
267
268 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
269 test_4() {
270         test_mkdir -i 1 $DIR/$tdir
271
272         touch $DIR/$tdir/$tfile ||
273                 error "Create file under remote directory failed"
274
275         rmdir $DIR/$tdir &&
276                 error "Expect error removing in-use dir $DIR/$tdir"
277
278         test -d $DIR/$tdir || error "Remote directory disappeared"
279
280         rm -rf $DIR/$tdir || error "remove remote dir error"
281 }
282 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
283
284 test_5() {
285         test_mkdir $DIR/$tdir
286         test_mkdir $DIR/$tdir/d2
287         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
288         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
289         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
290 }
291 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
292
293 test_6a() {
294         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
295         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
296         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
297                 error "$tfile does not have perm 0666 or UID $UID"
298         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
299         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
300                 error "$tfile should be 0666 and owned by UID $UID"
301 }
302 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
303
304 test_6c() {
305         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
306
307         touch $DIR/$tfile
308         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
309         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
310                 error "$tfile should be owned by UID $RUNAS_ID"
311         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
312         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
313                 error "$tfile should be owned by UID $RUNAS_ID"
314 }
315 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
316
317 test_6e() {
318         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
319
320         touch $DIR/$tfile
321         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
322         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
323                 error "$tfile should be owned by GID $UID"
324         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
325         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
326                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
327 }
328 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
329
330 test_6g() {
331         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
332
333         test_mkdir $DIR/$tdir
334         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
335         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
336         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
337         test_mkdir $DIR/$tdir/d/subdir
338         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
339                 error "$tdir/d/subdir should be GID $RUNAS_GID"
340         if [[ $MDSCOUNT -gt 1 ]]; then
341                 # check remote dir sgid inherite
342                 $LFS mkdir -i 0 $DIR/$tdir.local ||
343                         error "mkdir $tdir.local failed"
344                 chmod g+s $DIR/$tdir.local ||
345                         error "chmod $tdir.local failed"
346                 chgrp $RUNAS_GID $DIR/$tdir.local ||
347                         error "chgrp $tdir.local failed"
348                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
349                         error "mkdir $tdir.remote failed"
350                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
351                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
352                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
353                         error "$tdir.remote should be mode 02755"
354         fi
355 }
356 run_test 6g "verify new dir in sgid dir inherits group"
357
358 test_6h() { # bug 7331
359         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
360
361         touch $DIR/$tfile || error "touch failed"
362         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
363         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
364                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
365         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
366                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
367 }
368 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
369
370 test_7a() {
371         test_mkdir $DIR/$tdir
372         $MCREATE $DIR/$tdir/$tfile
373         chmod 0666 $DIR/$tdir/$tfile
374         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
375                 error "$tdir/$tfile should be mode 0666"
376 }
377 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
378
379 test_7b() {
380         if [ ! -d $DIR/$tdir ]; then
381                 test_mkdir $DIR/$tdir
382         fi
383         $MCREATE $DIR/$tdir/$tfile
384         echo -n foo > $DIR/$tdir/$tfile
385         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
386         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
387 }
388 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
389
390 test_8() {
391         test_mkdir $DIR/$tdir
392         touch $DIR/$tdir/$tfile
393         chmod 0666 $DIR/$tdir/$tfile
394         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
395                 error "$tfile mode not 0666"
396 }
397 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
398
399 test_9() {
400         test_mkdir $DIR/$tdir
401         test_mkdir $DIR/$tdir/d2
402         test_mkdir $DIR/$tdir/d2/d3
403         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
404 }
405 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
406
407 test_10() {
408         test_mkdir $DIR/$tdir
409         test_mkdir $DIR/$tdir/d2
410         touch $DIR/$tdir/d2/$tfile
411         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
412                 error "$tdir/d2/$tfile not a file"
413 }
414 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
415
416 test_11() {
417         test_mkdir $DIR/$tdir
418         test_mkdir $DIR/$tdir/d2
419         chmod 0666 $DIR/$tdir/d2
420         chmod 0705 $DIR/$tdir/d2
421         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
422                 error "$tdir/d2 mode not 0705"
423 }
424 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
425
426 test_12() {
427         test_mkdir $DIR/$tdir
428         touch $DIR/$tdir/$tfile
429         chmod 0666 $DIR/$tdir/$tfile
430         chmod 0654 $DIR/$tdir/$tfile
431         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
432                 error "$tdir/d2 mode not 0654"
433 }
434 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
435
436 test_13() {
437         test_mkdir $DIR/$tdir
438         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
439         >  $DIR/$tdir/$tfile
440         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
441                 error "$tdir/$tfile size not 0 after truncate"
442 }
443 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
444
445 test_14() {
446         test_mkdir $DIR/$tdir
447         touch $DIR/$tdir/$tfile
448         rm $DIR/$tdir/$tfile
449         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
450 }
451 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
452
453 test_15() {
454         test_mkdir $DIR/$tdir
455         touch $DIR/$tdir/$tfile
456         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
457         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
458                 error "$tdir/${tfile_2} not a file after rename"
459         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
460 }
461 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
462
463 test_16() {
464         test_mkdir $DIR/$tdir
465         touch $DIR/$tdir/$tfile
466         rm -rf $DIR/$tdir/$tfile
467         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
468 }
469 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
470
471 test_17a() {
472         test_mkdir $DIR/$tdir
473         touch $DIR/$tdir/$tfile
474         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
475         ls -l $DIR/$tdir
476         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
477                 error "$tdir/l-exist not a symlink"
478         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
479                 error "$tdir/l-exist not referencing a file"
480         rm -f $DIR/$tdir/l-exist
481         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
482 }
483 run_test 17a "symlinks: create, remove (real)"
484
485 test_17b() {
486         test_mkdir $DIR/$tdir
487         ln -s no-such-file $DIR/$tdir/l-dangle
488         ls -l $DIR/$tdir
489         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
490                 error "$tdir/l-dangle not referencing no-such-file"
491         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
492                 error "$tdir/l-dangle not referencing non-existent file"
493         rm -f $DIR/$tdir/l-dangle
494         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
495 }
496 run_test 17b "symlinks: create, remove (dangling)"
497
498 test_17c() { # bug 3440 - don't save failed open RPC for replay
499         test_mkdir $DIR/$tdir
500         ln -s foo $DIR/$tdir/$tfile
501         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
502 }
503 run_test 17c "symlinks: open dangling (should return error)"
504
505 test_17d() {
506         test_mkdir $DIR/$tdir
507         ln -s foo $DIR/$tdir/$tfile
508         touch $DIR/$tdir/$tfile || error "creating to new symlink"
509 }
510 run_test 17d "symlinks: create dangling"
511
512 test_17e() {
513         test_mkdir $DIR/$tdir
514         local foo=$DIR/$tdir/$tfile
515         ln -s $foo $foo || error "create symlink failed"
516         ls -l $foo || error "ls -l failed"
517         ls $foo && error "ls not failed" || true
518 }
519 run_test 17e "symlinks: create recursive symlink (should return error)"
520
521 test_17f() {
522         test_mkdir $DIR/$tdir
523         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
524         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
525         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
526         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
527         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
528         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
529         ls -l  $DIR/$tdir
530 }
531 run_test 17f "symlinks: long and very long symlink name"
532
533 # str_repeat(S, N) generate a string that is string S repeated N times
534 str_repeat() {
535         local s=$1
536         local n=$2
537         local ret=''
538         while [ $((n -= 1)) -ge 0 ]; do
539                 ret=$ret$s
540         done
541         echo $ret
542 }
543
544 # Long symlinks and LU-2241
545 test_17g() {
546         test_mkdir $DIR/$tdir
547         local TESTS="59 60 61 4094 4095"
548
549         # Fix for inode size boundary in 2.1.4
550         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
551                 TESTS="4094 4095"
552
553         # Patch not applied to 2.2 or 2.3 branches
554         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
555         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
556                 TESTS="4094 4095"
557
558         # skip long symlink name for rhel6.5.
559         # rhel6.5 has a limit (PATH_MAX - sizeof(struct filename))
560         grep -q '6.5' /etc/redhat-release &>/dev/null &&
561                 TESTS="59 60 61 4062 4063"
562
563         for i in $TESTS; do
564                 local SYMNAME=$(str_repeat 'x' $i)
565                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
566                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
567         done
568 }
569 run_test 17g "symlinks: really long symlink name and inode boundaries"
570
571 test_17h() { #bug 17378
572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
573         remote_mds_nodsh && skip "remote MDS with nodsh"
574
575         local mdt_idx
576
577         test_mkdir $DIR/$tdir
578         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
579         $LFS setstripe -c -1 $DIR/$tdir
580         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
581         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
582         touch $DIR/$tdir/$tfile || true
583 }
584 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
585
586 test_17i() { #bug 20018
587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
588         remote_mds_nodsh && skip "remote MDS with nodsh"
589
590         local foo=$DIR/$tdir/$tfile
591         local mdt_idx
592
593         test_mkdir -c1 $DIR/$tdir
594         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
595         ln -s $foo $foo || error "create symlink failed"
596 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
597         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
598         ls -l $foo && error "error not detected"
599         return 0
600 }
601 run_test 17i "don't panic on short symlink (should return error)"
602
603 test_17k() { #bug 22301
604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
605         [[ -z "$(which rsync 2>/dev/null)" ]] &&
606                 skip "no rsync command"
607         rsync --help | grep -q xattr ||
608                 skip_env "$(rsync --version | head -n1) does not support xattrs"
609         test_mkdir $DIR/$tdir
610         test_mkdir $DIR/$tdir.new
611         touch $DIR/$tdir/$tfile
612         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
613         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
614                 error "rsync failed with xattrs enabled"
615 }
616 run_test 17k "symlinks: rsync with xattrs enabled"
617
618 test_17l() { # LU-279
619         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
620                 skip "no getfattr command"
621
622         test_mkdir $DIR/$tdir
623         touch $DIR/$tdir/$tfile
624         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
625         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
626                 # -h to not follow symlinks. -m '' to list all the xattrs.
627                 # grep to remove first line: '# file: $path'.
628                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
629                 do
630                         lgetxattr_size_check $path $xattr ||
631                                 error "lgetxattr_size_check $path $xattr failed"
632                 done
633         done
634 }
635 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
636
637 # LU-1540
638 test_17m() {
639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
640         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
641         remote_mds_nodsh && skip "remote MDS with nodsh"
642         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
643         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
644                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
645
646         local short_sym="0123456789"
647         local wdir=$DIR/$tdir
648         local i
649
650         test_mkdir $wdir
651         long_sym=$short_sym
652         # create a long symlink file
653         for ((i = 0; i < 4; ++i)); do
654                 long_sym=${long_sym}${long_sym}
655         done
656
657         echo "create 512 short and long symlink files under $wdir"
658         for ((i = 0; i < 256; ++i)); do
659                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
660                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
661         done
662
663         echo "erase them"
664         rm -f $wdir/*
665         sync
666         wait_delete_completed
667
668         echo "recreate the 512 symlink files with a shorter string"
669         for ((i = 0; i < 512; ++i)); do
670                 # rewrite the symlink file with a shorter string
671                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
672                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
673         done
674
675         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
676         local devname=$(mdsdevname $mds_index)
677
678         echo "stop and checking mds${mds_index}:"
679         # e2fsck should not return error
680         stop mds${mds_index}
681         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
682         rc=$?
683
684         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
685                 error "start mds${mds_index} failed"
686         df $MOUNT > /dev/null 2>&1
687         [ $rc -eq 0 ] ||
688                 error "e2fsck detected error for short/long symlink: rc=$rc"
689         rm -f $wdir/*
690 }
691 run_test 17m "run e2fsck against MDT which contains short/long symlink"
692
693 check_fs_consistency_17n() {
694         local mdt_index
695         local rc=0
696
697         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
698         # so it only check MDT1/MDT2 instead of all of MDTs.
699         for mdt_index in 1 2; do
700                 local devname=$(mdsdevname $mdt_index)
701                 # e2fsck should not return error
702                 stop mds${mdt_index}
703                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
704                         rc=$((rc + $?))
705
706                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
707                         error "mount mds$mdt_index failed"
708                 df $MOUNT > /dev/null 2>&1
709         done
710         return $rc
711 }
712
713 test_17n() {
714         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
716         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
717         remote_mds_nodsh && skip "remote MDS with nodsh"
718         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
719         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
720                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
721
722         local i
723
724         test_mkdir $DIR/$tdir
725         for ((i=0; i<10; i++)); do
726                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
727                         error "create remote dir error $i"
728                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
729                         error "create files under remote dir failed $i"
730         done
731
732         check_fs_consistency_17n ||
733                 error "e2fsck report error after create files under remote dir"
734
735         for ((i = 0; i < 10; i++)); do
736                 rm -rf $DIR/$tdir/remote_dir_${i} ||
737                         error "destroy remote dir error $i"
738         done
739
740         check_fs_consistency_17n ||
741                 error "e2fsck report error after unlink files under remote dir"
742
743         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
744                 skip "lustre < 2.4.50 does not support migrate mv"
745
746         for ((i = 0; i < 10; i++)); do
747                 mkdir -p $DIR/$tdir/remote_dir_${i}
748                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
749                         error "create files under remote dir failed $i"
750                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
751                         error "migrate remote dir error $i"
752         done
753         check_fs_consistency_17n || error "e2fsck report error after migration"
754
755         for ((i = 0; i < 10; i++)); do
756                 rm -rf $DIR/$tdir/remote_dir_${i} ||
757                         error "destroy remote dir error $i"
758         done
759
760         check_fs_consistency_17n || error "e2fsck report error after unlink"
761 }
762 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
763
764 test_17o() {
765         remote_mds_nodsh && skip "remote MDS with nodsh"
766         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
767                 skip "Need MDS version at least 2.3.64"
768
769         local wdir=$DIR/${tdir}o
770         local mdt_index
771         local rc=0
772
773         test_mkdir $wdir
774         touch $wdir/$tfile
775         mdt_index=$($LFS getstripe -m $wdir/$tfile)
776         mdt_index=$((mdt_index + 1))
777
778         cancel_lru_locks mdc
779         #fail mds will wait the failover finish then set
780         #following fail_loc to avoid interfer the recovery process.
781         fail mds${mdt_index}
782
783         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
784         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
785         ls -l $wdir/$tfile && rc=1
786         do_facet mds${mdt_index} lctl set_param fail_loc=0
787         [[ $rc -eq 0 ]] || error "stat file should fail"
788 }
789 run_test 17o "stat file with incompat LMA feature"
790
791 test_18() {
792         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
793         ls $DIR || error "Failed to ls $DIR: $?"
794 }
795 run_test 18 "touch .../f ; ls ... =============================="
796
797 test_19a() {
798         touch $DIR/$tfile
799         ls -l $DIR
800         rm $DIR/$tfile
801         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
802 }
803 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
804
805 test_19b() {
806         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
807 }
808 run_test 19b "ls -l .../f19 (should return error) =============="
809
810 test_19c() {
811         [ $RUNAS_ID -eq $UID ] &&
812                 skip_env "RUNAS_ID = UID = $UID -- skipping"
813
814         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
815 }
816 run_test 19c "$RUNAS touch .../f19 (should return error) =="
817
818 test_19d() {
819         cat $DIR/f19 && error || true
820 }
821 run_test 19d "cat .../f19 (should return error) =============="
822
823 test_20() {
824         touch $DIR/$tfile
825         rm $DIR/$tfile
826         touch $DIR/$tfile
827         rm $DIR/$tfile
828         touch $DIR/$tfile
829         rm $DIR/$tfile
830         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
831 }
832 run_test 20 "touch .../f ; ls -l ..."
833
834 test_21() {
835         test_mkdir $DIR/$tdir
836         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
837         ln -s dangle $DIR/$tdir/link
838         echo foo >> $DIR/$tdir/link
839         cat $DIR/$tdir/dangle
840         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
841         $CHECKSTAT -f -t file $DIR/$tdir/link ||
842                 error "$tdir/link not linked to a file"
843 }
844 run_test 21 "write to dangling link"
845
846 test_22() {
847         local wdir=$DIR/$tdir
848         test_mkdir $wdir
849         chown $RUNAS_ID:$RUNAS_GID $wdir
850         (cd $wdir || error "cd $wdir failed";
851                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
852                 $RUNAS tar xf -)
853         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
854         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
855         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
856                 error "checkstat -u failed"
857 }
858 run_test 22 "unpack tar archive as non-root user"
859
860 # was test_23
861 test_23a() {
862         test_mkdir $DIR/$tdir
863         local file=$DIR/$tdir/$tfile
864
865         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
866         openfile -f O_CREAT:O_EXCL $file &&
867                 error "$file recreate succeeded" || true
868 }
869 run_test 23a "O_CREAT|O_EXCL in subdir"
870
871 test_23b() { # bug 18988
872         test_mkdir $DIR/$tdir
873         local file=$DIR/$tdir/$tfile
874
875         rm -f $file
876         echo foo > $file || error "write filed"
877         echo bar >> $file || error "append filed"
878         $CHECKSTAT -s 8 $file || error "wrong size"
879         rm $file
880 }
881 run_test 23b "O_APPEND check"
882
883 # LU-9409, size with O_APPEND and tiny writes
884 test_23c() {
885         local file=$DIR/$tfile
886
887         # single dd
888         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
889         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
890         rm -f $file
891
892         # racing tiny writes
893         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
894         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
895         wait
896         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
897         rm -f $file
898
899         #racing tiny & normal writes
900         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
901         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
902         wait
903         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
904         rm -f $file
905
906         #racing tiny & normal writes 2, ugly numbers
907         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
908         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
909         wait
910         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
911         rm -f $file
912 }
913 run_test 23c "O_APPEND size checks for tiny writes"
914
915 # LU-11069 file offset is correct after appending writes
916 test_23d() {
917         local file=$DIR/$tfile
918         local offset
919
920         echo CentaurHauls > $file
921         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
922         if ((offset != 26)); then
923                 error "wrong offset, expected 26, got '$offset'"
924         fi
925 }
926 run_test 23d "file offset is correct after appending writes"
927
928 # rename sanity
929 test_24a() {
930         echo '-- same directory rename'
931         test_mkdir $DIR/$tdir
932         touch $DIR/$tdir/$tfile.1
933         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
934         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
935 }
936 run_test 24a "rename file to non-existent target"
937
938 test_24b() {
939         test_mkdir $DIR/$tdir
940         touch $DIR/$tdir/$tfile.{1,2}
941         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
942         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
943         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
944 }
945 run_test 24b "rename file to existing target"
946
947 test_24c() {
948         test_mkdir $DIR/$tdir
949         test_mkdir $DIR/$tdir/d$testnum.1
950         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
951         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
952         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
953 }
954 run_test 24c "rename directory to non-existent target"
955
956 test_24d() {
957         test_mkdir -c1 $DIR/$tdir
958         test_mkdir -c1 $DIR/$tdir/d$testnum.1
959         test_mkdir -c1 $DIR/$tdir/d$testnum.2
960         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
961         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
962         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
963 }
964 run_test 24d "rename directory to existing target"
965
966 test_24e() {
967         echo '-- cross directory renames --'
968         test_mkdir $DIR/R5a
969         test_mkdir $DIR/R5b
970         touch $DIR/R5a/f
971         mv $DIR/R5a/f $DIR/R5b/g
972         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
973         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
974 }
975 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
976
977 test_24f() {
978         test_mkdir $DIR/R6a
979         test_mkdir $DIR/R6b
980         touch $DIR/R6a/f $DIR/R6b/g
981         mv $DIR/R6a/f $DIR/R6b/g
982         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
983         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
984 }
985 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
986
987 test_24g() {
988         test_mkdir $DIR/R7a
989         test_mkdir $DIR/R7b
990         test_mkdir $DIR/R7a/d
991         mv $DIR/R7a/d $DIR/R7b/e
992         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
993         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
994 }
995 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
996
997 test_24h() {
998         test_mkdir -c1 $DIR/R8a
999         test_mkdir -c1 $DIR/R8b
1000         test_mkdir -c1 $DIR/R8a/d
1001         test_mkdir -c1 $DIR/R8b/e
1002         mrename $DIR/R8a/d $DIR/R8b/e
1003         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1004         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1005 }
1006 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1007
1008 test_24i() {
1009         echo "-- rename error cases"
1010         test_mkdir $DIR/R9
1011         test_mkdir $DIR/R9/a
1012         touch $DIR/R9/f
1013         mrename $DIR/R9/f $DIR/R9/a
1014         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1015         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1016         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1017 }
1018 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1019
1020 test_24j() {
1021         test_mkdir $DIR/R10
1022         mrename $DIR/R10/f $DIR/R10/g
1023         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1024         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1025         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1026 }
1027 run_test 24j "source does not exist ============================"
1028
1029 test_24k() {
1030         test_mkdir $DIR/R11a
1031         test_mkdir $DIR/R11a/d
1032         touch $DIR/R11a/f
1033         mv $DIR/R11a/f $DIR/R11a/d
1034         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1035         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1036 }
1037 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1038
1039 # bug 2429 - rename foo foo foo creates invalid file
1040 test_24l() {
1041         f="$DIR/f24l"
1042         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1043 }
1044 run_test 24l "Renaming a file to itself ========================"
1045
1046 test_24m() {
1047         f="$DIR/f24m"
1048         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1049         # on ext3 this does not remove either the source or target files
1050         # though the "expected" operation would be to remove the source
1051         $CHECKSTAT -t file ${f} || error "${f} missing"
1052         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1053 }
1054 run_test 24m "Renaming a file to a hard link to itself ========="
1055
1056 test_24n() {
1057     f="$DIR/f24n"
1058     # this stats the old file after it was renamed, so it should fail
1059     touch ${f}
1060     $CHECKSTAT ${f} || error "${f} missing"
1061     mv ${f} ${f}.rename
1062     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1063     $CHECKSTAT -a ${f} || error "${f} exists"
1064 }
1065 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1066
1067 test_24o() {
1068         test_mkdir $DIR/$tdir
1069         rename_many -s random -v -n 10 $DIR/$tdir
1070 }
1071 run_test 24o "rename of files during htree split"
1072
1073 test_24p() {
1074         test_mkdir $DIR/R12a
1075         test_mkdir $DIR/R12b
1076         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1077         mrename $DIR/R12a $DIR/R12b
1078         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1079         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1080         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1081         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1082 }
1083 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1084
1085 cleanup_multiop_pause() {
1086         trap 0
1087         kill -USR1 $MULTIPID
1088 }
1089
1090 test_24q() {
1091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1092
1093         test_mkdir $DIR/R13a
1094         test_mkdir $DIR/R13b
1095         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1096         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1097         MULTIPID=$!
1098
1099         trap cleanup_multiop_pause EXIT
1100         mrename $DIR/R13a $DIR/R13b
1101         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1102         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1103         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1104         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1105         cleanup_multiop_pause
1106         wait $MULTIPID || error "multiop close failed"
1107 }
1108 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1109
1110 test_24r() { #bug 3789
1111         test_mkdir $DIR/R14a
1112         test_mkdir $DIR/R14a/b
1113         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1114         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1115         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1116 }
1117 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1118
1119 test_24s() {
1120         test_mkdir $DIR/R15a
1121         test_mkdir $DIR/R15a/b
1122         test_mkdir $DIR/R15a/b/c
1123         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1124         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1125         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1126 }
1127 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1128 test_24t() {
1129         test_mkdir $DIR/R16a
1130         test_mkdir $DIR/R16a/b
1131         test_mkdir $DIR/R16a/b/c
1132         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1133         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1134         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1135 }
1136 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1137
1138 test_24u() { # bug12192
1139         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1140         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1141 }
1142 run_test 24u "create stripe file"
1143
1144 simple_cleanup_common() {
1145         local rc=0
1146         trap 0
1147         [ -z "$DIR" -o -z "$tdir" ] && return 0
1148
1149         local start=$SECONDS
1150         rm -rf $DIR/$tdir
1151         rc=$?
1152         wait_delete_completed
1153         echo "cleanup time $((SECONDS - start))"
1154         return $rc
1155 }
1156
1157 max_pages_per_rpc() {
1158         local mdtname="$(printf "MDT%04x" ${1:-0})"
1159         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1160 }
1161
1162 test_24v() {
1163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1164
1165         local nrfiles=${COUNT:-100000}
1166         local fname="$DIR/$tdir/$tfile"
1167
1168         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1169         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1170
1171         test_mkdir "$(dirname $fname)"
1172         # assume MDT0000 has the fewest inodes
1173         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1174         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1175         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1176
1177         trap simple_cleanup_common EXIT
1178
1179         createmany -m "$fname" $nrfiles
1180
1181         cancel_lru_locks mdc
1182         lctl set_param mdc.*.stats clear
1183
1184         # was previously test_24D: LU-6101
1185         # readdir() returns correct number of entries after cursor reload
1186         local num_ls=$(ls $DIR/$tdir | wc -l)
1187         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1188         local num_all=$(ls -a $DIR/$tdir | wc -l)
1189         if [ $num_ls -ne $nrfiles -o $num_uniq -ne $nrfiles -o \
1190              $num_all -ne $((nrfiles + 2)) ]; then
1191                 error "Expected $nrfiles files, got $num_ls " \
1192                         "($num_uniq unique $num_all .&..)"
1193         fi
1194         # LU-5 large readdir
1195         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1196         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1197         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1198         # take into account of overhead in lu_dirpage header and end mark in
1199         # each page, plus one in rpc_num calculation.
1200         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1201         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1202         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1203         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1204         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1205         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1206         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1207         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1208                 error "large readdir doesn't take effect: " \
1209                       "$mds_readpage should be about $rpc_max"
1210
1211         simple_cleanup_common
1212 }
1213 run_test 24v "list large directory (test hash collision, b=17560)"
1214
1215 test_24w() { # bug21506
1216         SZ1=234852
1217         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1218         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1219         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1220         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1221         [[ "$SZ1" -eq "$SZ2" ]] ||
1222                 error "Error reading at the end of the file $tfile"
1223 }
1224 run_test 24w "Reading a file larger than 4Gb"
1225
1226 test_24x() {
1227         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1229         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1230                 skip "Need MDS version at least 2.7.56"
1231
1232         local MDTIDX=1
1233         local remote_dir=$DIR/$tdir/remote_dir
1234
1235         test_mkdir $DIR/$tdir
1236         $LFS mkdir -i $MDTIDX $remote_dir ||
1237                 error "create remote directory failed"
1238
1239         test_mkdir $DIR/$tdir/src_dir
1240         touch $DIR/$tdir/src_file
1241         test_mkdir $remote_dir/tgt_dir
1242         touch $remote_dir/tgt_file
1243
1244         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1245                 error "rename dir cross MDT failed!"
1246
1247         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1248                 error "rename file cross MDT failed!"
1249
1250         touch $DIR/$tdir/ln_file
1251         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1252                 error "ln file cross MDT failed"
1253
1254         rm -rf $DIR/$tdir || error "Can not delete directories"
1255 }
1256 run_test 24x "cross MDT rename/link"
1257
1258 test_24y() {
1259         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1261
1262         local remote_dir=$DIR/$tdir/remote_dir
1263         local mdtidx=1
1264
1265         test_mkdir $DIR/$tdir
1266         $LFS mkdir -i $mdtidx $remote_dir ||
1267                 error "create remote directory failed"
1268
1269         test_mkdir $remote_dir/src_dir
1270         touch $remote_dir/src_file
1271         test_mkdir $remote_dir/tgt_dir
1272         touch $remote_dir/tgt_file
1273
1274         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1275                 error "rename subdir in the same remote dir failed!"
1276
1277         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1278                 error "rename files in the same remote dir failed!"
1279
1280         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1281                 error "link files in the same remote dir failed!"
1282
1283         rm -rf $DIR/$tdir || error "Can not delete directories"
1284 }
1285 run_test 24y "rename/link on the same dir should succeed"
1286
1287 test_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 -o $u -ne $NFILES -o $v -ne $((NFILES + 2)) ] ; then
1328                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1329         fi
1330
1331         simple_cleanup_common || error "Can not delete directories"
1332 }
1333 run_test 24A "readdir() returns correct number of entries."
1334
1335 test_24B() { # LU-4805
1336         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1337
1338         local count
1339
1340         test_mkdir $DIR/$tdir
1341         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1342                 error "create striped dir failed"
1343
1344         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1345         [ $count -eq 2 ] || error "Expected 2, got $count"
1346
1347         touch $DIR/$tdir/striped_dir/a
1348
1349         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1350         [ $count -eq 3 ] || error "Expected 3, got $count"
1351
1352         touch $DIR/$tdir/striped_dir/.f
1353
1354         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1355         [ $count -eq 4 ] || error "Expected 4, got $count"
1356
1357         rm -rf $DIR/$tdir || error "Can not delete directories"
1358 }
1359 run_test 24B "readdir for striped dir return correct number of entries"
1360
1361 test_24C() {
1362         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1363
1364         mkdir $DIR/$tdir
1365         mkdir $DIR/$tdir/d0
1366         mkdir $DIR/$tdir/d1
1367
1368         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1369                 error "create striped dir failed"
1370
1371         cd $DIR/$tdir/d0/striped_dir
1372
1373         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1374         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1375         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1376
1377         [ "$d0_ino" = "$parent_ino" ] ||
1378                 error ".. wrong, expect $d0_ino, get $parent_ino"
1379
1380         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1381                 error "mv striped dir failed"
1382
1383         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1384
1385         [ "$d1_ino" = "$parent_ino" ] ||
1386                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1387 }
1388 run_test 24C "check .. in striped dir"
1389
1390 test_24E() {
1391         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1393
1394         mkdir -p $DIR/$tdir
1395         mkdir $DIR/$tdir/src_dir
1396         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1397                 error "create remote source failed"
1398
1399         touch $DIR/$tdir/src_dir/src_child/a
1400
1401         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1402                 error "create remote target dir failed"
1403
1404         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1405                 error "create remote target child failed"
1406
1407         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1408                 error "rename dir cross MDT failed!"
1409
1410         find $DIR/$tdir
1411
1412         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1413                 error "src_child still exists after rename"
1414
1415         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1416                 error "missing file(a) after rename"
1417
1418         rm -rf $DIR/$tdir || error "Can not delete directories"
1419 }
1420 run_test 24E "cross MDT rename/link"
1421
1422 test_24F () {
1423         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1424
1425         local repeats=1000
1426         [ "$SLOW" = "no" ] && repeats=100
1427
1428         mkdir -p $DIR/$tdir
1429
1430         echo "$repeats repeats"
1431         for ((i = 0; i < repeats; i++)); do
1432                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1433                 touch $DIR/$tdir/test/a || error "touch fails"
1434                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1435                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1436         done
1437
1438         true
1439 }
1440 run_test 24F "hash order vs readdir (LU-11330)"
1441
1442 test_25a() {
1443         echo '== symlink sanity ============================================='
1444
1445         test_mkdir $DIR/d25
1446         ln -s d25 $DIR/s25
1447         touch $DIR/s25/foo ||
1448                 error "File creation in symlinked directory failed"
1449 }
1450 run_test 25a "create file in symlinked directory ==============="
1451
1452 test_25b() {
1453         [ ! -d $DIR/d25 ] && test_25a
1454         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1455 }
1456 run_test 25b "lookup file in symlinked directory ==============="
1457
1458 test_26a() {
1459         test_mkdir $DIR/d26
1460         test_mkdir $DIR/d26/d26-2
1461         ln -s d26/d26-2 $DIR/s26
1462         touch $DIR/s26/foo || error "File creation failed"
1463 }
1464 run_test 26a "multiple component symlink ======================="
1465
1466 test_26b() {
1467         test_mkdir -p $DIR/$tdir/d26-2
1468         ln -s $tdir/d26-2/foo $DIR/s26-2
1469         touch $DIR/s26-2 || error "File creation failed"
1470 }
1471 run_test 26b "multiple component symlink at end of lookup ======"
1472
1473 test_26c() {
1474         test_mkdir $DIR/d26.2
1475         touch $DIR/d26.2/foo
1476         ln -s d26.2 $DIR/s26.2-1
1477         ln -s s26.2-1 $DIR/s26.2-2
1478         ln -s s26.2-2 $DIR/s26.2-3
1479         chmod 0666 $DIR/s26.2-3/foo
1480 }
1481 run_test 26c "chain of symlinks"
1482
1483 # recursive symlinks (bug 439)
1484 test_26d() {
1485         ln -s d26-3/foo $DIR/d26-3
1486 }
1487 run_test 26d "create multiple component recursive symlink"
1488
1489 test_26e() {
1490         [ ! -h $DIR/d26-3 ] && test_26d
1491         rm $DIR/d26-3
1492 }
1493 run_test 26e "unlink multiple component recursive symlink"
1494
1495 # recursive symlinks (bug 7022)
1496 test_26f() {
1497         test_mkdir $DIR/$tdir
1498         test_mkdir $DIR/$tdir/$tfile
1499         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1500         test_mkdir -p lndir/bar1
1501         test_mkdir $DIR/$tdir/$tfile/$tfile
1502         cd $tfile                || error "cd $tfile failed"
1503         ln -s .. dotdot          || error "ln dotdot failed"
1504         ln -s dotdot/lndir lndir || error "ln lndir failed"
1505         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1506         output=`ls $tfile/$tfile/lndir/bar1`
1507         [ "$output" = bar1 ] && error "unexpected output"
1508         rm -r $tfile             || error "rm $tfile failed"
1509         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1510 }
1511 run_test 26f "rm -r of a directory which has recursive symlink"
1512
1513 test_27a() {
1514         test_mkdir $DIR/$tdir
1515         $LFS getstripe $DIR/$tdir
1516         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1517         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1518         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1519 }
1520 run_test 27a "one stripe file"
1521
1522 test_27b() {
1523         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1524
1525         test_mkdir $DIR/$tdir
1526         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1527         $LFS getstripe -c $DIR/$tdir/$tfile
1528         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1529                 error "two-stripe file doesn't have two stripes"
1530
1531         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1532 }
1533 run_test 27b "create and write to two stripe file"
1534
1535 test_27d() {
1536         test_mkdir $DIR/$tdir
1537         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1538                 error "setstripe failed"
1539         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1540         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1541 }
1542 run_test 27d "create file with default settings"
1543
1544 test_27e() {
1545         # LU-5839 adds check for existed layout before setting it
1546         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1547                 skip "Need MDS version at least 2.7.56"
1548
1549         test_mkdir $DIR/$tdir
1550         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1551         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1552         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1553 }
1554 run_test 27e "setstripe existing file (should return error)"
1555
1556 test_27f() {
1557         test_mkdir $DIR/$tdir
1558         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1559                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1560         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1561                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1562         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1563         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1564 }
1565 run_test 27f "setstripe with bad stripe size (should return error)"
1566
1567 test_27g() {
1568         test_mkdir $DIR/$tdir
1569         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1570         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1571                 error "$DIR/$tdir/$tfile has object"
1572 }
1573 run_test 27g "$LFS getstripe with no objects"
1574
1575 test_27i() {
1576         test_mkdir $DIR/$tdir
1577         touch $DIR/$tdir/$tfile || error "touch failed"
1578         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1579                 error "missing objects"
1580 }
1581 run_test 27i "$LFS getstripe with some objects"
1582
1583 test_27j() {
1584         test_mkdir $DIR/$tdir
1585         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1586                 error "setstripe failed" || true
1587 }
1588 run_test 27j "setstripe with bad stripe offset (should return error)"
1589
1590 test_27k() { # bug 2844
1591         test_mkdir $DIR/$tdir
1592         local file=$DIR/$tdir/$tfile
1593         local ll_max_blksize=$((4 * 1024 * 1024))
1594         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1595         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1596         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1597         dd if=/dev/zero of=$file bs=4k count=1
1598         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1599         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1600 }
1601 run_test 27k "limit i_blksize for broken user apps"
1602
1603 test_27l() {
1604         mcreate $DIR/$tfile || error "creating file"
1605         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1606                 error "setstripe should have failed" || true
1607 }
1608 run_test 27l "check setstripe permissions (should return error)"
1609
1610 test_27m() {
1611         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1612
1613         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1614                    head -n1)
1615         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1616                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1617         fi
1618         trap simple_cleanup_common EXIT
1619         test_mkdir $DIR/$tdir
1620         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1621         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1622                 error "dd should fill OST0"
1623         i=2
1624         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1625                 i=$((i + 1))
1626                 [ $i -gt 256 ] && break
1627         done
1628         i=$((i + 1))
1629         touch $DIR/$tdir/$tfile.$i
1630         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1631             awk '{print $1}'| grep -w "0") ] &&
1632                 error "OST0 was full but new created file still use it"
1633         i=$((i + 1))
1634         touch $DIR/$tdir/$tfile.$i
1635         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1636             awk '{print $1}'| grep -w "0") ] &&
1637                 error "OST0 was full but new created file still use it"
1638         simple_cleanup_common
1639 }
1640 run_test 27m "create file while OST0 was full"
1641
1642 sleep_maxage() {
1643         local delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1644                       awk '{ print $1 * 2; exit; }')
1645         sleep $delay
1646 }
1647
1648 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1649 # if the OST isn't full anymore.
1650 reset_enospc() {
1651         local OSTIDX=${1:-""}
1652
1653         local list=$(comma_list $(osts_nodes))
1654         [ "$OSTIDX" ] && list=$(facet_host ost$((OSTIDX + 1)))
1655
1656         do_nodes $list lctl set_param fail_loc=0
1657         sync    # initiate all OST_DESTROYs from MDS to OST
1658         sleep_maxage
1659 }
1660
1661 exhaust_precreations() {
1662         local OSTIDX=$1
1663         local FAILLOC=$2
1664         local FAILIDX=${3:-$OSTIDX}
1665         local ofacet=ost$((OSTIDX + 1))
1666
1667         test_mkdir -p -c1 $DIR/$tdir
1668         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1669         local mfacet=mds$((mdtidx + 1))
1670         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1671
1672         local OST=$(ostname_from_index $OSTIDX)
1673
1674         # on the mdt's osc
1675         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1676         local last_id=$(do_facet $mfacet lctl get_param -n \
1677                         osc.$mdtosc_proc1.prealloc_last_id)
1678         local next_id=$(do_facet $mfacet lctl get_param -n \
1679                         osc.$mdtosc_proc1.prealloc_next_id)
1680
1681         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1682         do_facet $mfacet lctl get_param osc.$mdtosc_proc2.prealloc*
1683
1684         test_mkdir -p $DIR/$tdir/${OST}
1685         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1686 #define OBD_FAIL_OST_ENOSPC              0x215
1687         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1688         echo "Creating to objid $last_id on ost $OST..."
1689         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1690         do_facet $mfacet lctl get_param osc.$mdtosc_proc2.prealloc*
1691         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1692         sleep_maxage
1693 }
1694
1695 exhaust_all_precreations() {
1696         local i
1697         for (( i=0; i < OSTCOUNT; i++ )) ; do
1698                 exhaust_precreations $i $1 -1
1699         done
1700 }
1701
1702 test_27n() {
1703         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1705         remote_mds_nodsh && skip "remote MDS with nodsh"
1706         remote_ost_nodsh && skip "remote OST with nodsh"
1707
1708         reset_enospc
1709         rm -f $DIR/$tdir/$tfile
1710         exhaust_precreations 0 0x80000215
1711         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1712         touch $DIR/$tdir/$tfile || error "touch failed"
1713         $LFS getstripe $DIR/$tdir/$tfile
1714         reset_enospc
1715 }
1716 run_test 27n "create file with some full OSTs"
1717
1718 test_27o() {
1719         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1721         remote_mds_nodsh && skip "remote MDS with nodsh"
1722         remote_ost_nodsh && skip "remote OST with nodsh"
1723
1724         reset_enospc
1725         rm -f $DIR/$tdir/$tfile
1726         exhaust_all_precreations 0x215
1727
1728         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1729
1730         reset_enospc
1731         rm -rf $DIR/$tdir/*
1732 }
1733 run_test 27o "create file with all full OSTs (should error)"
1734
1735 test_27p() {
1736         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1738         remote_mds_nodsh && skip "remote MDS with nodsh"
1739         remote_ost_nodsh && skip "remote OST with nodsh"
1740
1741         reset_enospc
1742         rm -f $DIR/$tdir/$tfile
1743         test_mkdir $DIR/$tdir
1744
1745         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1746         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1747         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1748
1749         exhaust_precreations 0 0x80000215
1750         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1751         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1752         $LFS getstripe $DIR/$tdir/$tfile
1753
1754         reset_enospc
1755 }
1756 run_test 27p "append to a truncated file with some full OSTs"
1757
1758 test_27q() {
1759         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1761         remote_mds_nodsh && skip "remote MDS with nodsh"
1762         remote_ost_nodsh && skip "remote OST with nodsh"
1763
1764         reset_enospc
1765         rm -f $DIR/$tdir/$tfile
1766
1767         test_mkdir $DIR/$tdir
1768         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1769         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1770                 error "truncate $DIR/$tdir/$tfile failed"
1771         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1772
1773         exhaust_all_precreations 0x215
1774
1775         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1776         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1777
1778         reset_enospc
1779 }
1780 run_test 27q "append to truncated file with all OSTs full (should error)"
1781
1782 test_27r() {
1783         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1785         remote_mds_nodsh && skip "remote MDS with nodsh"
1786         remote_ost_nodsh && skip "remote OST with nodsh"
1787
1788         reset_enospc
1789         rm -f $DIR/$tdir/$tfile
1790         exhaust_precreations 0 0x80000215
1791
1792         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1793
1794         reset_enospc
1795 }
1796 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1797
1798 test_27s() { # bug 10725
1799         test_mkdir $DIR/$tdir
1800         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1801         local stripe_count=0
1802         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1803         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1804                 error "stripe width >= 2^32 succeeded" || true
1805
1806 }
1807 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1808
1809 test_27t() { # bug 10864
1810         WDIR=$(pwd)
1811         WLFS=$(which lfs)
1812         cd $DIR
1813         touch $tfile
1814         $WLFS getstripe $tfile
1815         cd $WDIR
1816 }
1817 run_test 27t "check that utils parse path correctly"
1818
1819 test_27u() { # bug 4900
1820         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1821         remote_mds_nodsh && skip "remote MDS with nodsh"
1822
1823         local index
1824         local list=$(comma_list $(mdts_nodes))
1825
1826 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1827         do_nodes $list $LCTL set_param fail_loc=0x139
1828         test_mkdir -p $DIR/$tdir
1829         trap simple_cleanup_common EXIT
1830         createmany -o $DIR/$tdir/t- 1000
1831         do_nodes $list $LCTL set_param fail_loc=0
1832
1833         TLOG=$TMP/$tfile.getstripe
1834         $LFS getstripe $DIR/$tdir > $TLOG
1835         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1836         unlinkmany $DIR/$tdir/t- 1000
1837         trap 0
1838         [[ $OBJS -gt 0 ]] &&
1839                 error "$OBJS objects created on OST-0. See $TLOG" ||
1840                 rm -f $TLOG
1841 }
1842 run_test 27u "skip object creation on OSC w/o objects"
1843
1844 test_27v() { # bug 4900
1845         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1847         remote_mds_nodsh && skip "remote MDS with nodsh"
1848         remote_ost_nodsh && skip "remote OST with nodsh"
1849
1850         exhaust_all_precreations 0x215
1851         reset_enospc
1852
1853         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1854
1855         touch $DIR/$tdir/$tfile
1856         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
1857         # all except ost1
1858         for (( i=1; i < OSTCOUNT; i++ )); do
1859                 do_facet ost$i lctl set_param fail_loc=0x705
1860         done
1861         local START=`date +%s`
1862         createmany -o $DIR/$tdir/$tfile 32
1863
1864         local FINISH=`date +%s`
1865         local TIMEOUT=`lctl get_param -n timeout`
1866         local PROCESS=$((FINISH - START))
1867         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
1868                error "$FINISH - $START >= $TIMEOUT / 2"
1869         sleep $((TIMEOUT / 2 - PROCESS))
1870         reset_enospc
1871 }
1872 run_test 27v "skip object creation on slow OST"
1873
1874 test_27w() { # bug 10997
1875         test_mkdir $DIR/$tdir
1876         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
1877         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
1878                 error "stripe size $size != 65536" || true
1879         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
1880                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
1881 }
1882 run_test 27w "check $LFS setstripe -S and getstrip -d options"
1883
1884 test_27wa() {
1885         [[ $OSTCOUNT -lt 2 ]] &&
1886                 skip_env "skipping multiple stripe count/offset test"
1887
1888         test_mkdir $DIR/$tdir
1889         for i in $(seq 1 $OSTCOUNT); do
1890                 offset=$((i - 1))
1891                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
1892                         error "setstripe -c $i -i $offset failed"
1893                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
1894                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
1895                 [ $count -ne $i ] && error "stripe count $count != $i" || true
1896                 [ $index -ne $offset ] &&
1897                         error "stripe offset $index != $offset" || true
1898         done
1899 }
1900 run_test 27wa "check $LFS setstripe -c -i options"
1901
1902 test_27x() {
1903         remote_ost_nodsh && skip "remote OST with nodsh"
1904         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1906
1907         OFFSET=$(($OSTCOUNT - 1))
1908         OSTIDX=0
1909         local OST=$(ostname_from_index $OSTIDX)
1910
1911         test_mkdir $DIR/$tdir
1912         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
1913         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
1914         sleep_maxage
1915         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
1916         for i in $(seq 0 $OFFSET); do
1917                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
1918                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
1919                 error "OST0 was degraded but new created file still use it"
1920         done
1921         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
1922 }
1923 run_test 27x "create files while OST0 is degraded"
1924
1925 test_27y() {
1926         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1927         remote_mds_nodsh && skip "remote MDS with nodsh"
1928         remote_ost_nodsh && skip "remote OST with nodsh"
1929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1930
1931         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
1932         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
1933                 osc.$mdtosc.prealloc_last_id)
1934         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
1935                 osc.$mdtosc.prealloc_next_id)
1936         local fcount=$((last_id - next_id))
1937         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
1938         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
1939
1940         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
1941                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
1942         local OST_DEACTIVE_IDX=-1
1943         local OSC
1944         local OSTIDX
1945         local OST
1946
1947         for OSC in $MDS_OSCS; do
1948                 OST=$(osc_to_ost $OSC)
1949                 OSTIDX=$(index_from_ostuuid $OST)
1950                 if [ $OST_DEACTIVE_IDX == -1 ]; then
1951                         OST_DEACTIVE_IDX=$OSTIDX
1952                 fi
1953                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
1954                         echo $OSC "is Deactivated:"
1955                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
1956                 fi
1957         done
1958
1959         OSTIDX=$(index_from_ostuuid $OST)
1960         test_mkdir $DIR/$tdir
1961         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
1962
1963         for OSC in $MDS_OSCS; do
1964                 OST=$(osc_to_ost $OSC)
1965                 OSTIDX=$(index_from_ostuuid $OST)
1966                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
1967                         echo $OST "is degraded:"
1968                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
1969                                                 obdfilter.$OST.degraded=1
1970                 fi
1971         done
1972
1973         sleep_maxage
1974         createmany -o $DIR/$tdir/$tfile $fcount
1975
1976         for OSC in $MDS_OSCS; do
1977                 OST=$(osc_to_ost $OSC)
1978                 OSTIDX=$(index_from_ostuuid $OST)
1979                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
1980                         echo $OST "is recovered from degraded:"
1981                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
1982                                                 obdfilter.$OST.degraded=0
1983                 else
1984                         do_facet $SINGLEMDS lctl --device %$OSC activate
1985                 fi
1986         done
1987
1988         # all osp devices get activated, hence -1 stripe count restored
1989         local stripe_count=0
1990
1991         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
1992         # devices get activated.
1993         sleep_maxage
1994         $LFS setstripe -c -1 $DIR/$tfile
1995         stripe_count=$($LFS getstripe -c $DIR/$tfile)
1996         rm -f $DIR/$tfile
1997         [ $stripe_count -ne $OSTCOUNT ] &&
1998                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
1999         return 0
2000 }
2001 run_test 27y "create files while OST0 is degraded and the rest inactive"
2002
2003 check_seq_oid()
2004 {
2005         log "check file $1"
2006
2007         lmm_count=$($LFS getstripe -c $1)
2008         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2009         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2010
2011         local old_ifs="$IFS"
2012         IFS=$'[:]'
2013         fid=($($LFS path2fid $1))
2014         IFS="$old_ifs"
2015
2016         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2017         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2018
2019         # compare lmm_seq and lu_fid->f_seq
2020         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2021         # compare lmm_object_id and lu_fid->oid
2022         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2023
2024         # check the trusted.fid attribute of the OST objects of the file
2025         local have_obdidx=false
2026         local stripe_nr=0
2027         $LFS getstripe $1 | while read obdidx oid hex seq; do
2028                 # skip lines up to and including "obdidx"
2029                 [ -z "$obdidx" ] && break
2030                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2031                 $have_obdidx || continue
2032
2033                 local ost=$((obdidx + 1))
2034                 local dev=$(ostdevname $ost)
2035                 local oid_hex
2036
2037                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2038
2039                 seq=$(echo $seq | sed -e "s/^0x//g")
2040                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2041                         oid_hex=$(echo $oid)
2042                 else
2043                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2044                 fi
2045                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2046
2047                 local ff=""
2048                 #
2049                 # Don't unmount/remount the OSTs if we don't need to do that.
2050                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2051                 # update too, until that use mount/ll_decode_filter_fid/mount.
2052                 # Re-enable when debugfs will understand new filter_fid.
2053                 #
2054                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2055                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2056                                 $dev 2>/dev/null" | grep "parent=")
2057                 fi
2058                 if [ -z "$ff" ]; then
2059                         stop ost$ost
2060                         mount_fstype ost$ost
2061                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2062                                 $(facet_mntpt ost$ost)/$obj_file)
2063                         unmount_fstype ost$ost
2064                         start ost$ost $dev $OST_MOUNT_OPTS
2065                         clients_up
2066                 fi
2067
2068                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2069
2070                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2071
2072                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2073                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2074                 #
2075                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2076                 #       stripe_size=1048576 component_id=1 component_start=0 \
2077                 #       component_end=33554432
2078                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2079                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2080                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2081                 local ff_pstripe
2082                 if grep -q 'stripe=' <<<$ff; then
2083                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2084                 else
2085                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2086                         # into f_ver in this case.  See comment on ff_parent.
2087                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2088                 fi
2089
2090                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2091                 [ $ff_pseq = $lmm_seq ] ||
2092                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2093                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2094                 [ $ff_poid = $lmm_oid ] ||
2095                         error "FF parent OID $ff_poid != $lmm_oid"
2096                 (($ff_pstripe == $stripe_nr)) ||
2097                         error "FF stripe $ff_pstripe != $stripe_nr"
2098
2099                 stripe_nr=$((stripe_nr + 1))
2100                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2101                         continue
2102                 if grep -q 'stripe_count=' <<<$ff; then
2103                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2104                                             -e 's/ .*//' <<<$ff)
2105                         [ $lmm_count = $ff_scnt ] ||
2106                                 error "FF stripe count $lmm_count != $ff_scnt"
2107                 fi
2108         done
2109 }
2110
2111 test_27z() {
2112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2113         remote_ost_nodsh && skip "remote OST with nodsh"
2114
2115         test_mkdir $DIR/$tdir
2116         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2117                 { error "setstripe -c -1 failed"; return 1; }
2118         # We need to send a write to every object to get parent FID info set.
2119         # This _should_ also work for setattr, but does not currently.
2120         # touch $DIR/$tdir/$tfile-1 ||
2121         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2122                 { error "dd $tfile-1 failed"; return 2; }
2123         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2124                 { error "setstripe -c -1 failed"; return 3; }
2125         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2126                 { error "dd $tfile-2 failed"; return 4; }
2127
2128         # make sure write RPCs have been sent to OSTs
2129         sync; sleep 5; sync
2130
2131         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2132         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2133 }
2134 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2135
2136 test_27A() { # b=19102
2137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2138
2139         save_layout_restore_at_exit $MOUNT
2140         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2141         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2142                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2143         local default_size=$($LFS getstripe -S $MOUNT)
2144         local default_offset=$($LFS getstripe -i $MOUNT)
2145         local dsize=$(do_facet $SINGLEMDS \
2146                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2147         [ $default_size -eq $dsize ] ||
2148                 error "stripe size $default_size != $dsize"
2149         [ $default_offset -eq -1 ] ||
2150                 error "stripe offset $default_offset != -1"
2151 }
2152 run_test 27A "check filesystem-wide default LOV EA values"
2153
2154 test_27B() { # LU-2523
2155         test_mkdir $DIR/$tdir
2156         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2157         touch $DIR/$tdir/f0
2158         # open f1 with O_LOV_DELAY_CREATE
2159         # rename f0 onto f1
2160         # call setstripe ioctl on open file descriptor for f1
2161         # close
2162         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2163                 $DIR/$tdir/f0
2164
2165         rm -f $DIR/$tdir/f1
2166         # open f1 with O_LOV_DELAY_CREATE
2167         # unlink f1
2168         # call setstripe ioctl on open file descriptor for f1
2169         # close
2170         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2171
2172         # Allow multiop to fail in imitation of NFS's busted semantics.
2173         true
2174 }
2175 run_test 27B "call setstripe on open unlinked file/rename victim"
2176
2177 test_27C() { #LU-2871
2178         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2179
2180         declare -a ost_idx
2181         local index
2182         local found
2183         local i
2184         local j
2185
2186         test_mkdir $DIR/$tdir
2187         cd $DIR/$tdir
2188         for i in $(seq 0 $((OSTCOUNT - 1))); do
2189                 # set stripe across all OSTs starting from OST$i
2190                 $LFS setstripe -i $i -c -1 $tfile$i
2191                 # get striping information
2192                 ost_idx=($($LFS getstripe $tfile$i |
2193                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2194                 echo ${ost_idx[@]}
2195
2196                 # check the layout
2197                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2198                         error "${#ost_idx[@]} != $OSTCOUNT"
2199
2200                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2201                         found=0
2202                         for j in $(echo ${ost_idx[@]}); do
2203                                 if [ $index -eq $j ]; then
2204                                         found=1
2205                                         break
2206                                 fi
2207                         done
2208                         [ $found = 1 ] ||
2209                                 error "Can not find $index in ${ost_idx[@]}"
2210                 done
2211         done
2212 }
2213 run_test 27C "check full striping across all OSTs"
2214
2215 test_27D() {
2216         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2217         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2218         remote_mds_nodsh && skip "remote MDS with nodsh"
2219
2220         local POOL=${POOL:-testpool}
2221         local first_ost=0
2222         local last_ost=$(($OSTCOUNT - 1))
2223         local ost_step=1
2224         local ost_list=$(seq $first_ost $ost_step $last_ost)
2225         local ost_range="$first_ost $last_ost $ost_step"
2226
2227         if ! combined_mgs_mds ; then
2228                 mount_mgs_client
2229         fi
2230
2231         test_mkdir $DIR/$tdir
2232         pool_add $POOL || error "pool_add failed"
2233         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2234
2235         local skip27D
2236         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2237                 skip27D+="-s 29"
2238         [ $MDS1_VERSION -lt $(version_code 2.9.55) -o \
2239           $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2240                 skip27D+=" -s 30,31"
2241         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2242                 error "llapi_layout_test failed"
2243
2244         destroy_test_pools || error "destroy test pools failed"
2245
2246         if ! combined_mgs_mds ; then
2247                 umount_mgs_client
2248         fi
2249 }
2250 run_test 27D "validate llapi_layout API"
2251
2252 # Verify that default_easize is increased from its initial value after
2253 # accessing a widely striped file.
2254 test_27E() {
2255         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2256         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2257                 skip "client does not have LU-3338 fix"
2258
2259         # 72 bytes is the minimum space required to store striping
2260         # information for a file striped across one OST:
2261         # (sizeof(struct lov_user_md_v3) +
2262         #  sizeof(struct lov_user_ost_data_v1))
2263         local min_easize=72
2264         $LCTL set_param -n llite.*.default_easize $min_easize ||
2265                 error "lctl set_param failed"
2266         local easize=$($LCTL get_param -n llite.*.default_easize)
2267
2268         [ $easize -eq $min_easize ] ||
2269                 error "failed to set default_easize"
2270
2271         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2272                 error "setstripe failed"
2273         cat $DIR/$tfile
2274         rm $DIR/$tfile
2275
2276         easize=$($LCTL get_param -n llite.*.default_easize)
2277
2278         [ $easize -gt $min_easize ] ||
2279                 error "default_easize not updated"
2280 }
2281 run_test 27E "check that default extended attribute size properly increases"
2282
2283 test_27F() { # LU-5346/LU-7975
2284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2285         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2286         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2287                 skip "Need MDS version at least 2.8.51"
2288         remote_ost_nodsh && skip "remote OST with nodsh"
2289
2290         test_mkdir $DIR/$tdir
2291         rm -f $DIR/$tdir/f0
2292         $LFS setstripe -c 2 $DIR/$tdir
2293
2294         # stop all OSTs to reproduce situation for LU-7975 ticket
2295         for num in $(seq $OSTCOUNT); do
2296                 stop ost$num
2297         done
2298
2299         # open/create f0 with O_LOV_DELAY_CREATE
2300         # truncate f0 to a non-0 size
2301         # close
2302         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2303
2304         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2305         # open/write it again to force delayed layout creation
2306         cat /etc/hosts > $DIR/$tdir/f0 &
2307         catpid=$!
2308
2309         # restart OSTs
2310         for num in $(seq $OSTCOUNT); do
2311                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2312                         error "ost$num failed to start"
2313         done
2314
2315         wait $catpid || error "cat failed"
2316
2317         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2318         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2319                 error "wrong stripecount"
2320
2321 }
2322 run_test 27F "Client resend delayed layout creation with non-zero size"
2323
2324 test_27G() { #LU-10629
2325         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2326                 skip "Need MDS version at least 2.11.51"
2327         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2328         remote_mds_nodsh && skip "remote MDS with nodsh"
2329         local POOL=${POOL:-testpool}
2330         local ostrange="0 0 1"
2331
2332         test_mkdir $DIR/$tdir
2333         pool_add $POOL || error "pool_add failed"
2334         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2335         $LFS setstripe -p $POOL $DIR/$tdir
2336
2337         local pool=$($LFS getstripe -p $DIR/$tdir)
2338
2339         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2340
2341         $LFS setstripe -d $DIR/$tdir
2342
2343         pool=$($LFS getstripe -p $DIR/$tdir)
2344
2345         rmdir $DIR/$tdir
2346
2347         [ -z "$pool" ] || error "'$pool' is not empty"
2348 }
2349 run_test 27G "Clear OST pool from stripe"
2350
2351 test_27H() {
2352         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2353                 skip "Need MDS version newer than 2.11.54"
2354         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2355         test_mkdir $DIR/$tdir
2356         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2357         touch $DIR/$tdir/$tfile
2358         $LFS getstripe -c $DIR/$tdir/$tfile
2359         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2360                 error "two-stripe file doesn't have two stripes"
2361
2362         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2363         $LFS getstripe -y $DIR/$tdir/$tfile
2364         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2365              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2366                 error "expected l_ost_idx: [02]$ not matched"
2367
2368         # make sure ost list has been cleared
2369         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2370         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2371                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2372         touch $DIR/$tdir/f3
2373         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2374 }
2375 run_test 27H "Set specific OSTs stripe"
2376
2377 # createtest also checks that device nodes are created and
2378 # then visible correctly (#2091)
2379 test_28() { # bug 2091
2380         test_mkdir $DIR/d28
2381         $CREATETEST $DIR/d28/ct || error "createtest failed"
2382 }
2383 run_test 28 "create/mknod/mkdir with bad file types ============"
2384
2385 test_29() {
2386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2387
2388         sync; sleep 1; sync # flush out any dirty pages from previous tests
2389         cancel_lru_locks
2390         test_mkdir $DIR/d29
2391         touch $DIR/d29/foo
2392         log 'first d29'
2393         ls -l $DIR/d29
2394
2395         declare -i LOCKCOUNTORIG=0
2396         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2397                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
2398         done
2399         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
2400
2401         declare -i LOCKUNUSEDCOUNTORIG=0
2402         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2403                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
2404         done
2405
2406         log 'second d29'
2407         ls -l $DIR/d29
2408         log 'done'
2409
2410         declare -i LOCKCOUNTCURRENT=0
2411         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2412                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
2413         done
2414
2415         declare -i LOCKUNUSEDCOUNTCURRENT=0
2416         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2417                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
2418         done
2419
2420         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
2421                 $LCTL set_param -n ldlm.dump_namespaces ""
2422                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
2423                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2424                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2425                 return 2
2426         fi
2427         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
2428                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
2429                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2430                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2431                 return 3
2432         fi
2433 }
2434 run_test 29 "IT_GETATTR regression  ============================"
2435
2436 test_30a() { # was test_30
2437         cp $(which ls) $DIR || cp /bin/ls $DIR
2438         $DIR/ls / || error "Can't execute binary from lustre"
2439         rm $DIR/ls
2440 }
2441 run_test 30a "execute binary from Lustre (execve) =============="
2442
2443 test_30b() {
2444         cp `which ls` $DIR || cp /bin/ls $DIR
2445         chmod go+rx $DIR/ls
2446         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
2447         rm $DIR/ls
2448 }
2449 run_test 30b "execute binary from Lustre as non-root ==========="
2450
2451 test_30c() { # b=22376
2452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2453
2454         cp `which ls` $DIR || cp /bin/ls $DIR
2455         chmod a-rw $DIR/ls
2456         cancel_lru_locks mdc
2457         cancel_lru_locks osc
2458         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
2459         rm -f $DIR/ls
2460 }
2461 run_test 30c "execute binary from Lustre without read perms ===="
2462
2463 test_31a() {
2464         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
2465         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
2466 }
2467 run_test 31a "open-unlink file =================================="
2468
2469 test_31b() {
2470         touch $DIR/f31 || error "touch $DIR/f31 failed"
2471         ln $DIR/f31 $DIR/f31b || error "ln failed"
2472         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
2473         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
2474 }
2475 run_test 31b "unlink file with multiple links while open ======="
2476
2477 test_31c() {
2478         touch $DIR/f31 || error "touch $DIR/f31 failed"
2479         ln $DIR/f31 $DIR/f31c || error "ln failed"
2480         multiop_bg_pause $DIR/f31 O_uc ||
2481                 error "multiop_bg_pause for $DIR/f31 failed"
2482         MULTIPID=$!
2483         $MULTIOP $DIR/f31c Ouc
2484         kill -USR1 $MULTIPID
2485         wait $MULTIPID
2486 }
2487 run_test 31c "open-unlink file with multiple links ============="
2488
2489 test_31d() {
2490         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
2491         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
2492 }
2493 run_test 31d "remove of open directory ========================="
2494
2495 test_31e() { # bug 2904
2496         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
2497 }
2498 run_test 31e "remove of open non-empty directory ==============="
2499
2500 test_31f() { # bug 4554
2501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2502
2503         set -vx
2504         test_mkdir $DIR/d31f
2505         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2506         cp /etc/hosts $DIR/d31f
2507         ls -l $DIR/d31f
2508         $LFS getstripe $DIR/d31f/hosts
2509         multiop_bg_pause $DIR/d31f D_c || return 1
2510         MULTIPID=$!
2511
2512         rm -rv $DIR/d31f || error "first of $DIR/d31f"
2513         test_mkdir $DIR/d31f
2514         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2515         cp /etc/hosts $DIR/d31f
2516         ls -l $DIR/d31f
2517         $LFS getstripe $DIR/d31f/hosts
2518         multiop_bg_pause $DIR/d31f D_c || return 1
2519         MULTIPID2=$!
2520
2521         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
2522         wait $MULTIPID || error "first opendir $MULTIPID failed"
2523
2524         sleep 6
2525
2526         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
2527         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
2528         set +vx
2529 }
2530 run_test 31f "remove of open directory with open-unlink file ==="
2531
2532 test_31g() {
2533         echo "-- cross directory link --"
2534         test_mkdir -c1 $DIR/${tdir}ga
2535         test_mkdir -c1 $DIR/${tdir}gb
2536         touch $DIR/${tdir}ga/f
2537         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
2538         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
2539         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
2540         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
2541         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
2542 }
2543 run_test 31g "cross directory link==============="
2544
2545 test_31h() {
2546         echo "-- cross directory link --"
2547         test_mkdir -c1 $DIR/${tdir}
2548         test_mkdir -c1 $DIR/${tdir}/dir
2549         touch $DIR/${tdir}/f
2550         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
2551         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
2552         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
2553         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
2554         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
2555 }
2556 run_test 31h "cross directory link under child==============="
2557
2558 test_31i() {
2559         echo "-- cross directory link --"
2560         test_mkdir -c1 $DIR/$tdir
2561         test_mkdir -c1 $DIR/$tdir/dir
2562         touch $DIR/$tdir/dir/f
2563         ln $DIR/$tdir/dir/f $DIR/$tdir/g
2564         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
2565         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
2566         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
2567         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
2568 }
2569 run_test 31i "cross directory link under parent==============="
2570
2571 test_31j() {
2572         test_mkdir -c1 -p $DIR/$tdir
2573         test_mkdir -c1 -p $DIR/$tdir/dir1
2574         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
2575         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
2576         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
2577         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
2578         return 0
2579 }
2580 run_test 31j "link for directory==============="
2581
2582 test_31k() {
2583         test_mkdir -c1 -p $DIR/$tdir
2584         touch $DIR/$tdir/s
2585         touch $DIR/$tdir/exist
2586         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
2587         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
2588         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
2589         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
2590         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
2591         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
2592         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
2593         return 0
2594 }
2595 run_test 31k "link to file: the same, non-existing, dir==============="
2596
2597 test_31m() {
2598         mkdir $DIR/d31m
2599         touch $DIR/d31m/s
2600         mkdir $DIR/d31m2
2601         touch $DIR/d31m2/exist
2602         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
2603         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
2604         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
2605         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
2606         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
2607         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
2608         return 0
2609 }
2610 run_test 31m "link to file: the same, non-existing, dir==============="
2611
2612 test_31n() {
2613         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
2614         nlink=$(stat --format=%h $DIR/$tfile)
2615         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
2616         local fd=$(free_fd)
2617         local cmd="exec $fd<$DIR/$tfile"
2618         eval $cmd
2619         cmd="exec $fd<&-"
2620         trap "eval $cmd" EXIT
2621         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
2622         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
2623         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
2624         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
2625         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
2626         eval $cmd
2627 }
2628 run_test 31n "check link count of unlinked file"
2629
2630 link_one() {
2631         local TEMPNAME=$(mktemp $1_XXXXXX)
2632         mlink $TEMPNAME $1 2> /dev/null &&
2633                 echo "$BASHPID: link $TEMPNAME to $1 succeeded"
2634         munlink $TEMPNAME
2635 }
2636
2637 test_31o() { # LU-2901
2638         test_mkdir $DIR/$tdir
2639         for LOOP in $(seq 100); do
2640                 rm -f $DIR/$tdir/$tfile*
2641                 for THREAD in $(seq 8); do
2642                         link_one $DIR/$tdir/$tfile.$LOOP &
2643                 done
2644                 wait
2645                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
2646                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
2647                         error "$LINKS duplicate links to $tfile.$LOOP" &&
2648                         break || true
2649         done
2650 }
2651 run_test 31o "duplicate hard links with same filename"
2652
2653 test_31p() {
2654         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
2655
2656         test_mkdir $DIR/$tdir
2657         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
2658         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
2659
2660         opendirunlink $DIR/$tdir/striped_dir/test1 ||
2661                 error "open unlink test1 failed"
2662         opendirunlink $DIR/$tdir/striped_dir/test2 ||
2663                 error "open unlink test2 failed"
2664
2665         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
2666                 error "test1 still exists"
2667         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
2668                 error "test2 still exists"
2669 }
2670 run_test 31p "remove of open striped directory"
2671
2672 cleanup_test32_mount() {
2673         local rc=0
2674         trap 0
2675         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
2676         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
2677         losetup -d $loopdev || true
2678         rm -rf $DIR/$tdir
2679         return $rc
2680 }
2681
2682 test_32a() {
2683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2684
2685         echo "== more mountpoints and symlinks ================="
2686         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2687         trap cleanup_test32_mount EXIT
2688         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2689         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2690                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2691         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
2692                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
2693         cleanup_test32_mount
2694 }
2695 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
2696
2697 test_32b() {
2698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2699
2700         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2701         trap cleanup_test32_mount EXIT
2702         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2703         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2704                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2705         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
2706                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
2707         cleanup_test32_mount
2708 }
2709 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
2710
2711 test_32c() {
2712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2713
2714         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2715         trap cleanup_test32_mount EXIT
2716         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2717         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2718                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2719         test_mkdir -p $DIR/$tdir/d2/test_dir
2720         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
2721                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
2722         cleanup_test32_mount
2723 }
2724 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
2725
2726 test_32d() {
2727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2728
2729         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2730         trap cleanup_test32_mount EXIT
2731         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2732         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2733                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2734         test_mkdir -p $DIR/$tdir/d2/test_dir
2735         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
2736                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
2737         cleanup_test32_mount
2738 }
2739 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
2740
2741 test_32e() {
2742         rm -fr $DIR/$tdir
2743         test_mkdir -p $DIR/$tdir/tmp
2744         local tmp_dir=$DIR/$tdir/tmp
2745         ln -s $DIR/$tdir $tmp_dir/symlink11
2746         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
2747         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
2748         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
2749 }
2750 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
2751
2752 test_32f() {
2753         rm -fr $DIR/$tdir
2754         test_mkdir -p $DIR/$tdir/tmp
2755         local tmp_dir=$DIR/$tdir/tmp
2756         ln -s $DIR/$tdir $tmp_dir/symlink11
2757         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
2758         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
2759         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
2760 }
2761 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
2762
2763 test_32g() {
2764         local tmp_dir=$DIR/$tdir/tmp
2765         test_mkdir -p $tmp_dir
2766         test_mkdir $DIR/${tdir}2
2767         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
2768         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
2769         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
2770         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
2771         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
2772         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
2773 }
2774 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
2775
2776 test_32h() {
2777         rm -fr $DIR/$tdir $DIR/${tdir}2
2778         tmp_dir=$DIR/$tdir/tmp
2779         test_mkdir -p $tmp_dir
2780         test_mkdir $DIR/${tdir}2
2781         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
2782         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
2783         ls $tmp_dir/symlink12 || error "listing symlink12"
2784         ls $DIR/$tdir/symlink02  || error "listing symlink02"
2785 }
2786 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
2787
2788 test_32i() {
2789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2790
2791         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2792         trap cleanup_test32_mount EXIT
2793         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2794         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2795                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2796         touch $DIR/$tdir/test_file
2797         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
2798                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
2799         cleanup_test32_mount
2800 }
2801 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
2802
2803 test_32j() {
2804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2805
2806         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2807         trap cleanup_test32_mount EXIT
2808         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2809         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2810                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2811         touch $DIR/$tdir/test_file
2812         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
2813                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
2814         cleanup_test32_mount
2815 }
2816 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
2817
2818 test_32k() {
2819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2820
2821         rm -fr $DIR/$tdir
2822         trap cleanup_test32_mount EXIT
2823         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2824         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2825                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2826         test_mkdir -p $DIR/$tdir/d2
2827         touch $DIR/$tdir/d2/test_file || error "touch failed"
2828         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
2829                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
2830         cleanup_test32_mount
2831 }
2832 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
2833
2834 test_32l() {
2835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2836
2837         rm -fr $DIR/$tdir
2838         trap cleanup_test32_mount EXIT
2839         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2840         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2841                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2842         test_mkdir -p $DIR/$tdir/d2
2843         touch $DIR/$tdir/d2/test_file || error "touch failed"
2844         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
2845                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
2846         cleanup_test32_mount
2847 }
2848 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
2849
2850 test_32m() {
2851         rm -fr $DIR/d32m
2852         test_mkdir -p $DIR/d32m/tmp
2853         TMP_DIR=$DIR/d32m/tmp
2854         ln -s $DIR $TMP_DIR/symlink11
2855         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
2856         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
2857                 error "symlink11 not a link"
2858         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
2859                 error "symlink01 not a link"
2860 }
2861 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
2862
2863 test_32n() {
2864         rm -fr $DIR/d32n
2865         test_mkdir -p $DIR/d32n/tmp
2866         TMP_DIR=$DIR/d32n/tmp
2867         ln -s $DIR $TMP_DIR/symlink11
2868         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
2869         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
2870         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
2871 }
2872 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
2873
2874 test_32o() {
2875         touch $DIR/$tfile
2876         test_mkdir -p $DIR/d32o/tmp
2877         TMP_DIR=$DIR/d32o/tmp
2878         ln -s $DIR/$tfile $TMP_DIR/symlink12
2879         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
2880         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
2881                 error "symlink12 not a link"
2882         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
2883         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
2884                 error "$DIR/d32o/tmp/symlink12 not file type"
2885         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
2886                 error "$DIR/d32o/symlink02 not file type"
2887 }
2888 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
2889
2890 test_32p() {
2891         log 32p_1
2892         rm -fr $DIR/d32p
2893         log 32p_2
2894         rm -f $DIR/$tfile
2895         log 32p_3
2896         touch $DIR/$tfile
2897         log 32p_4
2898         test_mkdir -p $DIR/d32p/tmp
2899         log 32p_5
2900         TMP_DIR=$DIR/d32p/tmp
2901         log 32p_6
2902         ln -s $DIR/$tfile $TMP_DIR/symlink12
2903         log 32p_7
2904         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
2905         log 32p_8
2906         cat $DIR/d32p/tmp/symlink12 ||
2907                 error "Can't open $DIR/d32p/tmp/symlink12"
2908         log 32p_9
2909         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
2910         log 32p_10
2911 }
2912 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
2913
2914 test_32q() {
2915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2916
2917         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2918         trap cleanup_test32_mount EXIT
2919         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2920         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
2921         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2922                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2923         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
2924         cleanup_test32_mount
2925 }
2926 run_test 32q "stat follows mountpoints in Lustre (should return error)"
2927
2928 test_32r() {
2929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2930
2931         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2932         trap cleanup_test32_mount EXIT
2933         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2934         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
2935         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2936                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2937         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
2938         cleanup_test32_mount
2939 }
2940 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
2941
2942 test_33aa() {
2943         rm -f $DIR/$tfile
2944         touch $DIR/$tfile
2945         chmod 444 $DIR/$tfile
2946         chown $RUNAS_ID $DIR/$tfile
2947         log 33_1
2948         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
2949         log 33_2
2950 }
2951 run_test 33aa "write file with mode 444 (should return error)"
2952
2953 test_33a() {
2954         rm -fr $DIR/$tdir
2955         test_mkdir $DIR/$tdir
2956         chown $RUNAS_ID $DIR/$tdir
2957         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
2958                 error "$RUNAS create $tdir/$tfile failed"
2959         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
2960                 error "open RDWR" || true
2961 }
2962 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
2963
2964 test_33b() {
2965         rm -fr $DIR/$tdir
2966         test_mkdir $DIR/$tdir
2967         chown $RUNAS_ID $DIR/$tdir
2968         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
2969 }
2970 run_test 33b "test open file with malformed flags (No panic)"
2971
2972 test_33c() {
2973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2974         remote_ost_nodsh && skip "remote OST with nodsh"
2975
2976         local ostnum
2977         local ostname
2978         local write_bytes
2979         local all_zeros
2980
2981         all_zeros=:
2982         rm -fr $DIR/$tdir
2983         test_mkdir $DIR/$tdir
2984         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
2985
2986         sync
2987         for ostnum in $(seq $OSTCOUNT); do
2988                 # test-framework's OST numbering is one-based, while Lustre's
2989                 # is zero-based
2990                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
2991                 # Parsing llobdstat's output sucks; we could grep the /proc
2992                 # path, but that's likely to not be as portable as using the
2993                 # llobdstat utility.  So we parse lctl output instead.
2994                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
2995                         obdfilter/$ostname/stats |
2996                         awk '/^write_bytes/ {print $7}' )
2997                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
2998                 if (( ${write_bytes:-0} > 0 ))
2999                 then
3000                         all_zeros=false
3001                         break;
3002                 fi
3003         done
3004
3005         $all_zeros || return 0
3006
3007         # Write four bytes
3008         echo foo > $DIR/$tdir/bar
3009         # Really write them
3010         sync
3011
3012         # Total up write_bytes after writing.  We'd better find non-zeros.
3013         for ostnum in $(seq $OSTCOUNT); do
3014                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3015                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3016                         obdfilter/$ostname/stats |
3017                         awk '/^write_bytes/ {print $7}' )
3018                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3019                 if (( ${write_bytes:-0} > 0 ))
3020                 then
3021                         all_zeros=false
3022                         break;
3023                 fi
3024         done
3025
3026         if $all_zeros
3027         then
3028                 for ostnum in $(seq $OSTCOUNT); do
3029                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3030                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3031                         do_facet ost$ostnum lctl get_param -n \
3032                                 obdfilter/$ostname/stats
3033                 done
3034                 error "OST not keeping write_bytes stats (b22312)"
3035         fi
3036 }
3037 run_test 33c "test llobdstat and write_bytes"
3038
3039 test_33d() {
3040         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3042
3043         local MDTIDX=1
3044         local remote_dir=$DIR/$tdir/remote_dir
3045
3046         test_mkdir $DIR/$tdir
3047         $LFS mkdir -i $MDTIDX $remote_dir ||
3048                 error "create remote directory failed"
3049
3050         touch $remote_dir/$tfile
3051         chmod 444 $remote_dir/$tfile
3052         chown $RUNAS_ID $remote_dir/$tfile
3053
3054         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3055
3056         chown $RUNAS_ID $remote_dir
3057         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3058                                         error "create" || true
3059         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3060                                     error "open RDWR" || true
3061         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3062 }
3063 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3064
3065 test_33e() {
3066         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3067
3068         mkdir $DIR/$tdir
3069
3070         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3071         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3072         mkdir $DIR/$tdir/local_dir
3073
3074         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3075         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3076         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3077
3078         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3079                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3080
3081         rmdir $DIR/$tdir/* || error "rmdir failed"
3082
3083         umask 777
3084         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3085         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3086         mkdir $DIR/$tdir/local_dir
3087
3088         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3089         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3090         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3091
3092         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3093                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3094
3095         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3096
3097         umask 000
3098         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3099         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3100         mkdir $DIR/$tdir/local_dir
3101
3102         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3103         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3104         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3105
3106         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3107                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3108 }
3109 run_test 33e "mkdir and striped directory should have same mode"
3110
3111 cleanup_33f() {
3112         trap 0
3113         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3114 }
3115
3116 test_33f() {
3117         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3118         remote_mds_nodsh && skip "remote MDS with nodsh"
3119
3120         mkdir $DIR/$tdir
3121         chmod go+rwx $DIR/$tdir
3122         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3123         trap cleanup_33f EXIT
3124
3125         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3126                 error "cannot create striped directory"
3127
3128         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3129                 error "cannot create files in striped directory"
3130
3131         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3132                 error "cannot remove files in striped directory"
3133
3134         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3135                 error "cannot remove striped directory"
3136
3137         cleanup_33f
3138 }
3139 run_test 33f "nonroot user can create, access, and remove a striped directory"
3140
3141 test_33g() {
3142         mkdir -p $DIR/$tdir/dir2
3143
3144         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3145         echo $err
3146         [[ $err =~ "exists" ]] || error "Not exists error"
3147 }
3148 run_test 33g "nonroot user create already existing root created file"
3149
3150 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3151 test_34a() {
3152         rm -f $DIR/f34
3153         $MCREATE $DIR/f34 || error "mcreate failed"
3154         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3155                 error "getstripe failed"
3156         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3157         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3158                 error "getstripe failed"
3159         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3160                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3161 }
3162 run_test 34a "truncate file that has not been opened ==========="
3163
3164 test_34b() {
3165         [ ! -f $DIR/f34 ] && test_34a
3166         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3167                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3168         $OPENFILE -f O_RDONLY $DIR/f34
3169         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3170                 error "getstripe failed"
3171         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3172                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3173 }
3174 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3175
3176 test_34c() {
3177         [ ! -f $DIR/f34 ] && test_34a
3178         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3179                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3180         $OPENFILE -f O_RDWR $DIR/f34
3181         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3182                 error "$LFS getstripe failed"
3183         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3184                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3185 }
3186 run_test 34c "O_RDWR opening file-with-size works =============="
3187
3188 test_34d() {
3189         [ ! -f $DIR/f34 ] && test_34a
3190         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3191                 error "dd failed"
3192         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3193                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3194         rm $DIR/f34
3195 }
3196 run_test 34d "write to sparse file ============================="
3197
3198 test_34e() {
3199         rm -f $DIR/f34e
3200         $MCREATE $DIR/f34e || error "mcreate failed"
3201         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3202         $CHECKSTAT -s 1000 $DIR/f34e ||
3203                 error "Size of $DIR/f34e not equal to 1000 bytes"
3204         $OPENFILE -f O_RDWR $DIR/f34e
3205         $CHECKSTAT -s 1000 $DIR/f34e ||
3206                 error "Size of $DIR/f34e not equal to 1000 bytes"
3207 }
3208 run_test 34e "create objects, some with size and some without =="
3209
3210 test_34f() { # bug 6242, 6243
3211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3212
3213         SIZE34F=48000
3214         rm -f $DIR/f34f
3215         $MCREATE $DIR/f34f || error "mcreate failed"
3216         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3217         dd if=$DIR/f34f of=$TMP/f34f
3218         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3219         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3220         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3221         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3222         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3223 }
3224 run_test 34f "read from a file with no objects until EOF ======="
3225
3226 test_34g() {
3227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3228
3229         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3230                 error "dd failed"
3231         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3232         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3233                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3234         cancel_lru_locks osc
3235         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3236                 error "wrong size after lock cancel"
3237
3238         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3239         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3240                 error "expanding truncate failed"
3241         cancel_lru_locks osc
3242         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3243                 error "wrong expanded size after lock cancel"
3244 }
3245 run_test 34g "truncate long file ==============================="
3246
3247 test_34h() {
3248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3249
3250         local gid=10
3251         local sz=1000
3252
3253         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3254         sync # Flush the cache so that multiop below does not block on cache
3255              # flush when getting the group lock
3256         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3257         MULTIPID=$!
3258
3259         # Since just timed wait is not good enough, let's do a sync write
3260         # that way we are sure enough time for a roundtrip + processing
3261         # passed + 2 seconds of extra margin.
3262         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3263         rm $DIR/${tfile}-1
3264         sleep 2
3265
3266         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3267                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3268                 kill -9 $MULTIPID
3269         fi
3270         wait $MULTIPID
3271         local nsz=`stat -c %s $DIR/$tfile`
3272         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3273 }
3274 run_test 34h "ftruncate file under grouplock should not block"
3275
3276 test_35a() {
3277         cp /bin/sh $DIR/f35a
3278         chmod 444 $DIR/f35a
3279         chown $RUNAS_ID $DIR/f35a
3280         $RUNAS $DIR/f35a && error || true
3281         rm $DIR/f35a
3282 }
3283 run_test 35a "exec file with mode 444 (should return and not leak)"
3284
3285 test_36a() {
3286         rm -f $DIR/f36
3287         utime $DIR/f36 || error "utime failed for MDS"
3288 }
3289 run_test 36a "MDS utime check (mknod, utime)"
3290
3291 test_36b() {
3292         echo "" > $DIR/f36
3293         utime $DIR/f36 || error "utime failed for OST"
3294 }
3295 run_test 36b "OST utime check (open, utime)"
3296
3297 test_36c() {
3298         rm -f $DIR/d36/f36
3299         test_mkdir $DIR/d36
3300         chown $RUNAS_ID $DIR/d36
3301         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3302 }
3303 run_test 36c "non-root MDS utime check (mknod, utime)"
3304
3305 test_36d() {
3306         [ ! -d $DIR/d36 ] && test_36c
3307         echo "" > $DIR/d36/f36
3308         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3309 }
3310 run_test 36d "non-root OST utime check (open, utime)"
3311
3312 test_36e() {
3313         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3314
3315         test_mkdir $DIR/$tdir
3316         touch $DIR/$tdir/$tfile
3317         $RUNAS utime $DIR/$tdir/$tfile &&
3318                 error "utime worked, expected failure" || true
3319 }
3320 run_test 36e "utime on non-owned file (should return error)"
3321
3322 subr_36fh() {
3323         local fl="$1"
3324         local LANG_SAVE=$LANG
3325         local LC_LANG_SAVE=$LC_LANG
3326         export LANG=C LC_LANG=C # for date language
3327
3328         DATESTR="Dec 20  2000"
3329         test_mkdir $DIR/$tdir
3330         lctl set_param fail_loc=$fl
3331         date; date +%s
3332         cp /etc/hosts $DIR/$tdir/$tfile
3333         sync & # write RPC generated with "current" inode timestamp, but delayed
3334         sleep 1
3335         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3336         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3337         cancel_lru_locks $OSC
3338         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3339         date; date +%s
3340         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3341                 echo "BEFORE: $LS_BEFORE" && \
3342                 echo "AFTER : $LS_AFTER" && \
3343                 echo "WANT  : $DATESTR" && \
3344                 error "$DIR/$tdir/$tfile timestamps changed" || true
3345
3346         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3347 }
3348
3349 test_36f() {
3350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3351
3352         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3353         subr_36fh "0x80000214"
3354 }
3355 run_test 36f "utime on file racing with OST BRW write =========="
3356
3357 test_36g() {
3358         remote_ost_nodsh && skip "remote OST with nodsh"
3359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3360         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
3361                 skip "Need MDS version at least 2.12.51"
3362
3363         local fmd_max_age
3364         local fmd
3365         local facet="ost1"
3366         local tgt="obdfilter"
3367
3368         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
3369
3370         test_mkdir $DIR/$tdir
3371         fmd_max_age=$(do_facet $facet \
3372                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
3373                 head -n 1")
3374
3375         echo "FMD max age: ${fmd_max_age}s"
3376         touch $DIR/$tdir/$tfile
3377         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3378                 gawk '{cnt=cnt+$1}  END{print cnt}')
3379         echo "FMD before: $fmd"
3380         [[ $fmd == 0 ]] &&
3381                 error "FMD wasn't create by touch"
3382         sleep $((fmd_max_age + 12))
3383         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3384                 gawk '{cnt=cnt+$1}  END{print cnt}')
3385         echo "FMD after: $fmd"
3386         [[ $fmd == 0 ]] ||
3387                 error "FMD wasn't expired by ping"
3388 }
3389 run_test 36g "FMD cache expiry ====================="
3390
3391 test_36h() {
3392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3393
3394         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
3395         subr_36fh "0x80000227"
3396 }
3397 run_test 36h "utime on file racing with OST BRW write =========="
3398
3399 test_36i() {
3400         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3401
3402         test_mkdir $DIR/$tdir
3403         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
3404
3405         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
3406         local new_mtime=$((mtime + 200))
3407
3408         #change Modify time of striped dir
3409         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
3410                         error "change mtime failed"
3411
3412         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
3413
3414         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
3415 }
3416 run_test 36i "change mtime on striped directory"
3417
3418 # test_37 - duplicate with tests 32q 32r
3419
3420 test_38() {
3421         local file=$DIR/$tfile
3422         touch $file
3423         openfile -f O_DIRECTORY $file
3424         local RC=$?
3425         local ENOTDIR=20
3426         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
3427         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
3428 }
3429 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
3430
3431 test_39a() { # was test_39
3432         touch $DIR/$tfile
3433         touch $DIR/${tfile}2
3434 #       ls -l  $DIR/$tfile $DIR/${tfile}2
3435 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
3436 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
3437         sleep 2
3438         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
3439         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
3440                 echo "mtime"
3441                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
3442                 echo "atime"
3443                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
3444                 echo "ctime"
3445                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
3446                 error "O_TRUNC didn't change timestamps"
3447         fi
3448 }
3449 run_test 39a "mtime changed on create"
3450
3451 test_39b() {
3452         test_mkdir -c1 $DIR/$tdir
3453         cp -p /etc/passwd $DIR/$tdir/fopen
3454         cp -p /etc/passwd $DIR/$tdir/flink
3455         cp -p /etc/passwd $DIR/$tdir/funlink
3456         cp -p /etc/passwd $DIR/$tdir/frename
3457         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
3458
3459         sleep 1
3460         echo "aaaaaa" >> $DIR/$tdir/fopen
3461         echo "aaaaaa" >> $DIR/$tdir/flink
3462         echo "aaaaaa" >> $DIR/$tdir/funlink
3463         echo "aaaaaa" >> $DIR/$tdir/frename
3464
3465         local open_new=`stat -c %Y $DIR/$tdir/fopen`
3466         local link_new=`stat -c %Y $DIR/$tdir/flink`
3467         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
3468         local rename_new=`stat -c %Y $DIR/$tdir/frename`
3469
3470         cat $DIR/$tdir/fopen > /dev/null
3471         ln $DIR/$tdir/flink $DIR/$tdir/flink2
3472         rm -f $DIR/$tdir/funlink2
3473         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
3474
3475         for (( i=0; i < 2; i++ )) ; do
3476                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
3477                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
3478                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
3479                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
3480
3481                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
3482                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
3483                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
3484                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
3485
3486                 cancel_lru_locks $OSC
3487                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3488         done
3489 }
3490 run_test 39b "mtime change on open, link, unlink, rename  ======"
3491
3492 # this should be set to past
3493 TEST_39_MTIME=`date -d "1 year ago" +%s`
3494
3495 # bug 11063
3496 test_39c() {
3497         touch $DIR1/$tfile
3498         sleep 2
3499         local mtime0=`stat -c %Y $DIR1/$tfile`
3500
3501         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3502         local mtime1=`stat -c %Y $DIR1/$tfile`
3503         [ "$mtime1" = $TEST_39_MTIME ] || \
3504                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
3505
3506         local d1=`date +%s`
3507         echo hello >> $DIR1/$tfile
3508         local d2=`date +%s`
3509         local mtime2=`stat -c %Y $DIR1/$tfile`
3510         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
3511                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
3512
3513         mv $DIR1/$tfile $DIR1/$tfile-1
3514
3515         for (( i=0; i < 2; i++ )) ; do
3516                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
3517                 [ "$mtime2" = "$mtime3" ] || \
3518                         error "mtime ($mtime2) changed (to $mtime3) on rename"
3519
3520                 cancel_lru_locks $OSC
3521                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3522         done
3523 }
3524 run_test 39c "mtime change on rename ==========================="
3525
3526 # bug 21114
3527 test_39d() {
3528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3529
3530         touch $DIR1/$tfile
3531         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3532
3533         for (( i=0; i < 2; i++ )) ; do
3534                 local mtime=`stat -c %Y $DIR1/$tfile`
3535                 [ $mtime = $TEST_39_MTIME ] || \
3536                         error "mtime($mtime) is not set to $TEST_39_MTIME"
3537
3538                 cancel_lru_locks $OSC
3539                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3540         done
3541 }
3542 run_test 39d "create, utime, stat =============================="
3543
3544 # bug 21114
3545 test_39e() {
3546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3547
3548         touch $DIR1/$tfile
3549         local mtime1=`stat -c %Y $DIR1/$tfile`
3550
3551         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3552
3553         for (( i=0; i < 2; i++ )) ; do
3554                 local mtime2=`stat -c %Y $DIR1/$tfile`
3555                 [ $mtime2 = $TEST_39_MTIME ] || \
3556                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
3557
3558                 cancel_lru_locks $OSC
3559                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3560         done
3561 }
3562 run_test 39e "create, stat, utime, stat ========================"
3563
3564 # bug 21114
3565 test_39f() {
3566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3567
3568         touch $DIR1/$tfile
3569         mtime1=`stat -c %Y $DIR1/$tfile`
3570
3571         sleep 2
3572         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3573
3574         for (( i=0; i < 2; i++ )) ; do
3575                 local mtime2=`stat -c %Y $DIR1/$tfile`
3576                 [ $mtime2 = $TEST_39_MTIME ] || \
3577                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
3578
3579                 cancel_lru_locks $OSC
3580                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3581         done
3582 }
3583 run_test 39f "create, stat, sleep, utime, stat ================="
3584
3585 # bug 11063
3586 test_39g() {
3587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3588
3589         echo hello >> $DIR1/$tfile
3590         local mtime1=`stat -c %Y $DIR1/$tfile`
3591
3592         sleep 2
3593         chmod o+r $DIR1/$tfile
3594
3595         for (( i=0; i < 2; i++ )) ; do
3596                 local mtime2=`stat -c %Y $DIR1/$tfile`
3597                 [ "$mtime1" = "$mtime2" ] || \
3598                         error "lost mtime: $mtime2, should be $mtime1"
3599
3600                 cancel_lru_locks $OSC
3601                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3602         done
3603 }
3604 run_test 39g "write, chmod, stat ==============================="
3605
3606 # bug 11063
3607 test_39h() {
3608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3609
3610         touch $DIR1/$tfile
3611         sleep 1
3612
3613         local d1=`date`
3614         echo hello >> $DIR1/$tfile
3615         local mtime1=`stat -c %Y $DIR1/$tfile`
3616
3617         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3618         local d2=`date`
3619         if [ "$d1" != "$d2" ]; then
3620                 echo "write and touch not within one second"
3621         else
3622                 for (( i=0; i < 2; i++ )) ; do
3623                         local mtime2=`stat -c %Y $DIR1/$tfile`
3624                         [ "$mtime2" = $TEST_39_MTIME ] || \
3625                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
3626
3627                         cancel_lru_locks $OSC
3628                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3629                 done
3630         fi
3631 }
3632 run_test 39h "write, utime within one second, stat ============="
3633
3634 test_39i() {
3635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3636
3637         touch $DIR1/$tfile
3638         sleep 1
3639
3640         echo hello >> $DIR1/$tfile
3641         local mtime1=`stat -c %Y $DIR1/$tfile`
3642
3643         mv $DIR1/$tfile $DIR1/$tfile-1
3644
3645         for (( i=0; i < 2; i++ )) ; do
3646                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
3647
3648                 [ "$mtime1" = "$mtime2" ] || \
3649                         error "lost mtime: $mtime2, should be $mtime1"
3650
3651                 cancel_lru_locks $OSC
3652                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3653         done
3654 }
3655 run_test 39i "write, rename, stat =============================="
3656
3657 test_39j() {
3658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3659
3660         start_full_debug_logging
3661         touch $DIR1/$tfile
3662         sleep 1
3663
3664         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
3665         lctl set_param fail_loc=0x80000412
3666         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
3667                 error "multiop failed"
3668         local multipid=$!
3669         local mtime1=`stat -c %Y $DIR1/$tfile`
3670
3671         mv $DIR1/$tfile $DIR1/$tfile-1
3672
3673         kill -USR1 $multipid
3674         wait $multipid || error "multiop close failed"
3675
3676         for (( i=0; i < 2; i++ )) ; do
3677                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
3678                 [ "$mtime1" = "$mtime2" ] ||
3679                         error "mtime is lost on close: $mtime2, " \
3680                               "should be $mtime1"
3681
3682                 cancel_lru_locks $OSC
3683                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3684         done
3685         lctl set_param fail_loc=0
3686         stop_full_debug_logging
3687 }
3688 run_test 39j "write, rename, close, stat ======================="
3689
3690 test_39k() {
3691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3692
3693         touch $DIR1/$tfile
3694         sleep 1
3695
3696         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
3697         local multipid=$!
3698         local mtime1=`stat -c %Y $DIR1/$tfile`
3699
3700         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3701
3702         kill -USR1 $multipid
3703         wait $multipid || error "multiop close failed"
3704
3705         for (( i=0; i < 2; i++ )) ; do
3706                 local mtime2=`stat -c %Y $DIR1/$tfile`
3707
3708                 [ "$mtime2" = $TEST_39_MTIME ] || \
3709                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
3710
3711                 cancel_lru_locks osc
3712                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3713         done
3714 }
3715 run_test 39k "write, utime, close, stat ========================"
3716
3717 # this should be set to future
3718 TEST_39_ATIME=`date -d "1 year" +%s`
3719
3720 test_39l() {
3721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3722         remote_mds_nodsh && skip "remote MDS with nodsh"
3723
3724         local atime_diff=$(do_facet $SINGLEMDS \
3725                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
3726         rm -rf $DIR/$tdir
3727         mkdir -p $DIR/$tdir
3728
3729         # test setting directory atime to future
3730         touch -a -d @$TEST_39_ATIME $DIR/$tdir
3731         local atime=$(stat -c %X $DIR/$tdir)
3732         [ "$atime" = $TEST_39_ATIME ] ||
3733                 error "atime is not set to future: $atime, $TEST_39_ATIME"
3734
3735         # test setting directory atime from future to now
3736         local now=$(date +%s)
3737         touch -a -d @$now $DIR/$tdir
3738
3739         atime=$(stat -c %X $DIR/$tdir)
3740         [ "$atime" -eq "$now"  ] ||
3741                 error "atime is not updated from future: $atime, $now"
3742
3743         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
3744         sleep 3
3745
3746         # test setting directory atime when now > dir atime + atime_diff
3747         local d1=$(date +%s)
3748         ls $DIR/$tdir
3749         local d2=$(date +%s)
3750         cancel_lru_locks mdc
3751         atime=$(stat -c %X $DIR/$tdir)
3752         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
3753                 error "atime is not updated  : $atime, should be $d2"
3754
3755         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
3756         sleep 3
3757
3758         # test not setting directory atime when now < dir atime + atime_diff
3759         ls $DIR/$tdir
3760         cancel_lru_locks mdc
3761         atime=$(stat -c %X $DIR/$tdir)
3762         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
3763                 error "atime is updated to $atime, should remain $d1<atime<$d2"
3764
3765         do_facet $SINGLEMDS \
3766                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
3767 }
3768 run_test 39l "directory atime update ==========================="
3769
3770 test_39m() {
3771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3772
3773         touch $DIR1/$tfile
3774         sleep 2
3775         local far_past_mtime=$(date -d "May 29 1953" +%s)
3776         local far_past_atime=$(date -d "Dec 17 1903" +%s)
3777
3778         touch -m -d @$far_past_mtime $DIR1/$tfile
3779         touch -a -d @$far_past_atime $DIR1/$tfile
3780
3781         for (( i=0; i < 2; i++ )) ; do
3782                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
3783                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
3784                         error "atime or mtime set incorrectly"
3785
3786                 cancel_lru_locks $OSC
3787                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3788         done
3789 }
3790 run_test 39m "test atime and mtime before 1970"
3791
3792 test_39n() { # LU-3832
3793         remote_mds_nodsh && skip "remote MDS with nodsh"
3794
3795         local atime_diff=$(do_facet $SINGLEMDS \
3796                 lctl get_param -n mdd.*MDT0000*.atime_diff)
3797         local atime0
3798         local atime1
3799         local atime2
3800
3801         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
3802
3803         rm -rf $DIR/$tfile
3804         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
3805         atime0=$(stat -c %X $DIR/$tfile)
3806
3807         sleep 5
3808         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
3809         atime1=$(stat -c %X $DIR/$tfile)
3810
3811         sleep 5
3812         cancel_lru_locks mdc
3813         cancel_lru_locks osc
3814         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
3815         atime2=$(stat -c %X $DIR/$tfile)
3816
3817         do_facet $SINGLEMDS \
3818                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
3819
3820         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
3821         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
3822 }
3823 run_test 39n "check that O_NOATIME is honored"
3824
3825 test_39o() {
3826         TESTDIR=$DIR/$tdir/$tfile
3827         [ -e $TESTDIR ] && rm -rf $TESTDIR
3828         mkdir -p $TESTDIR
3829         cd $TESTDIR
3830         links1=2
3831         ls
3832         mkdir a b
3833         ls
3834         links2=$(stat -c %h .)
3835         [ $(($links1 + 2)) != $links2 ] &&
3836                 error "wrong links count $(($links1 + 2)) != $links2"
3837         rmdir b
3838         links3=$(stat -c %h .)
3839         [ $(($links1 + 1)) != $links3 ] &&
3840                 error "wrong links count $links1 != $links3"
3841         return 0
3842 }
3843 run_test 39o "directory cached attributes updated after create"
3844
3845 test_39p() {
3846         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3847
3848         local MDTIDX=1
3849         TESTDIR=$DIR/$tdir/$tdir
3850         [ -e $TESTDIR ] && rm -rf $TESTDIR
3851         test_mkdir -p $TESTDIR
3852         cd $TESTDIR
3853         links1=2
3854         ls
3855         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
3856         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
3857         ls
3858         links2=$(stat -c %h .)
3859         [ $(($links1 + 2)) != $links2 ] &&
3860                 error "wrong links count $(($links1 + 2)) != $links2"
3861         rmdir remote_dir2
3862         links3=$(stat -c %h .)
3863         [ $(($links1 + 1)) != $links3 ] &&
3864                 error "wrong links count $links1 != $links3"
3865         return 0
3866 }
3867 run_test 39p "remote directory cached attributes updated after create ========"
3868
3869
3870 test_39q() { # LU-8041
3871         local testdir=$DIR/$tdir
3872         mkdir -p $testdir
3873         multiop_bg_pause $testdir D_c || error "multiop failed"
3874         local multipid=$!
3875         cancel_lru_locks mdc
3876         kill -USR1 $multipid
3877         local atime=$(stat -c %X $testdir)
3878         [ "$atime" -ne 0 ] || error "atime is zero"
3879 }
3880 run_test 39q "close won't zero out atime"
3881
3882 test_40() {
3883         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
3884         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
3885                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
3886         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
3887                 error "$tfile is not 4096 bytes in size"
3888 }
3889 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
3890
3891 test_41() {
3892         # bug 1553
3893         small_write $DIR/f41 18
3894 }
3895 run_test 41 "test small file write + fstat ====================="
3896
3897 count_ost_writes() {
3898         lctl get_param -n ${OSC}.*.stats |
3899                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
3900                         END { printf("%0.0f", writes) }'
3901 }
3902
3903 # decent default
3904 WRITEBACK_SAVE=500
3905 DIRTY_RATIO_SAVE=40
3906 MAX_DIRTY_RATIO=50
3907 BG_DIRTY_RATIO_SAVE=10
3908 MAX_BG_DIRTY_RATIO=25
3909
3910 start_writeback() {
3911         trap 0
3912         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
3913         # dirty_ratio, dirty_background_ratio
3914         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
3915                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
3916                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
3917                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
3918         else
3919                 # if file not here, we are a 2.4 kernel
3920                 kill -CONT `pidof kupdated`
3921         fi
3922 }
3923
3924 stop_writeback() {
3925         # setup the trap first, so someone cannot exit the test at the
3926         # exact wrong time and mess up a machine
3927         trap start_writeback EXIT
3928         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
3929         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
3930                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
3931                 sysctl -w vm.dirty_writeback_centisecs=0
3932                 sysctl -w vm.dirty_writeback_centisecs=0
3933                 # save and increase /proc/sys/vm/dirty_ratio
3934                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
3935                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
3936                 # save and increase /proc/sys/vm/dirty_background_ratio
3937                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
3938                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
3939         else
3940                 # if file not here, we are a 2.4 kernel
3941                 kill -STOP `pidof kupdated`
3942         fi
3943 }
3944
3945 # ensure that all stripes have some grant before we test client-side cache
3946 setup_test42() {
3947         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
3948                 dd if=/dev/zero of=$i bs=4k count=1
3949                 rm $i
3950         done
3951 }
3952
3953 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
3954 # file truncation, and file removal.
3955 test_42a() {
3956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3957
3958         setup_test42
3959         cancel_lru_locks $OSC
3960         stop_writeback
3961         sync; sleep 1; sync # just to be safe
3962         BEFOREWRITES=`count_ost_writes`
3963         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
3964         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
3965         AFTERWRITES=`count_ost_writes`
3966         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
3967                 error "$BEFOREWRITES < $AFTERWRITES"
3968         start_writeback
3969 }
3970 run_test 42a "ensure that we don't flush on close"
3971
3972 test_42b() {
3973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3974
3975         setup_test42
3976         cancel_lru_locks $OSC
3977         stop_writeback
3978         sync
3979         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
3980         BEFOREWRITES=$(count_ost_writes)
3981         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
3982         AFTERWRITES=$(count_ost_writes)
3983         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
3984                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
3985         fi
3986         BEFOREWRITES=$(count_ost_writes)
3987         sync || error "sync: $?"
3988         AFTERWRITES=$(count_ost_writes)
3989         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
3990                 error "$BEFOREWRITES < $AFTERWRITES on sync"
3991         fi
3992         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
3993         start_writeback
3994         return 0
3995 }
3996 run_test 42b "test destroy of file with cached dirty data ======"
3997
3998 # if these tests just want to test the effect of truncation,
3999 # they have to be very careful.  consider:
4000 # - the first open gets a {0,EOF}PR lock
4001 # - the first write conflicts and gets a {0, count-1}PW
4002 # - the rest of the writes are under {count,EOF}PW
4003 # - the open for truncate tries to match a {0,EOF}PR
4004 #   for the filesize and cancels the PWs.
4005 # any number of fixes (don't get {0,EOF} on open, match
4006 # composite locks, do smarter file size management) fix
4007 # this, but for now we want these tests to verify that
4008 # the cancellation with truncate intent works, so we
4009 # start the file with a full-file pw lock to match against
4010 # until the truncate.
4011 trunc_test() {
4012         test=$1
4013         file=$DIR/$test
4014         offset=$2
4015         cancel_lru_locks $OSC
4016         stop_writeback
4017         # prime the file with 0,EOF PW to match
4018         touch $file
4019         $TRUNCATE $file 0
4020         sync; sync
4021         # now the real test..
4022         dd if=/dev/zero of=$file bs=1024 count=100
4023         BEFOREWRITES=`count_ost_writes`
4024         $TRUNCATE $file $offset
4025         cancel_lru_locks $OSC
4026         AFTERWRITES=`count_ost_writes`
4027         start_writeback
4028 }
4029
4030 test_42c() {
4031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4032
4033         trunc_test 42c 1024
4034         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4035                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4036         rm $file
4037 }
4038 run_test 42c "test partial truncate of file with cached dirty data"
4039
4040 test_42d() {
4041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4042
4043         trunc_test 42d 0
4044         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4045                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4046         rm $file
4047 }
4048 run_test 42d "test complete truncate of file with cached dirty data"
4049
4050 test_42e() { # bug22074
4051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4052
4053         local TDIR=$DIR/${tdir}e
4054         local pages=16 # hardcoded 16 pages, don't change it.
4055         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4056         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4057         local max_dirty_mb
4058         local warmup_files
4059
4060         test_mkdir $DIR/${tdir}e
4061         $LFS setstripe -c 1 $TDIR
4062         createmany -o $TDIR/f $files
4063
4064         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4065
4066         # we assume that with $OSTCOUNT files, at least one of them will
4067         # be allocated on OST0.
4068         warmup_files=$((OSTCOUNT * max_dirty_mb))
4069         createmany -o $TDIR/w $warmup_files
4070
4071         # write a large amount of data into one file and sync, to get good
4072         # avail_grant number from OST.
4073         for ((i=0; i<$warmup_files; i++)); do
4074                 idx=$($LFS getstripe -i $TDIR/w$i)
4075                 [ $idx -ne 0 ] && continue
4076                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4077                 break
4078         done
4079         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4080         sync
4081         $LCTL get_param $proc_osc0/cur_dirty_bytes
4082         $LCTL get_param $proc_osc0/cur_grant_bytes
4083
4084         # create as much dirty pages as we can while not to trigger the actual
4085         # RPCs directly. but depends on the env, VFS may trigger flush during this
4086         # period, hopefully we are good.
4087         for ((i=0; i<$warmup_files; i++)); do
4088                 idx=$($LFS getstripe -i $TDIR/w$i)
4089                 [ $idx -ne 0 ] && continue
4090                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4091         done
4092         $LCTL get_param $proc_osc0/cur_dirty_bytes
4093         $LCTL get_param $proc_osc0/cur_grant_bytes
4094
4095         # perform the real test
4096         $LCTL set_param $proc_osc0/rpc_stats 0
4097         for ((;i<$files; i++)); do
4098                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4099                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4100         done
4101         sync
4102         $LCTL get_param $proc_osc0/rpc_stats
4103
4104         local percent=0
4105         local have_ppr=false
4106         $LCTL get_param $proc_osc0/rpc_stats |
4107                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4108                         # skip lines until we are at the RPC histogram data
4109                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4110                         $have_ppr || continue
4111
4112                         # we only want the percent stat for < 16 pages
4113                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4114
4115                         percent=$((percent + WPCT))
4116                         if [[ $percent -gt 15 ]]; then
4117                                 error "less than 16-pages write RPCs" \
4118                                       "$percent% > 15%"
4119                                 break
4120                         fi
4121                 done
4122         rm -rf $TDIR
4123 }
4124 run_test 42e "verify sub-RPC writes are not done synchronously"
4125
4126 test_43A() { # was test_43
4127         test_mkdir $DIR/$tdir
4128         cp -p /bin/ls $DIR/$tdir/$tfile
4129         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4130         pid=$!
4131         # give multiop a chance to open
4132         sleep 1
4133
4134         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4135         kill -USR1 $pid
4136 }
4137 run_test 43A "execution of file opened for write should return -ETXTBSY"
4138
4139 test_43a() {
4140         test_mkdir $DIR/$tdir
4141         cp -p $(which $MULTIOP) $DIR/$tdir/multiop ||
4142                 cp -p multiop $DIR/$tdir/multiop
4143         MULTIOP_PROG=$DIR/$tdir/multiop multiop_bg_pause $TMP/$tfile.junk O_c ||
4144                 error "multiop open $TMP/$tfile.junk failed"
4145         rm $TMP/$tfile.junk     # delete junk file on close (not part of test)
4146         MULTIOP_PID=$!
4147         $MULTIOP $DIR/$tdir/multiop Oc && error "expected error, got success"
4148         kill -USR1 $MULTIOP_PID || error "kill -USR1 PID $MULTIOP_PID failed"
4149         wait $MULTIOP_PID || error "wait PID $MULTIOP_PID failed"
4150 }
4151 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4152
4153 test_43b() {
4154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4155
4156         test_mkdir $DIR/$tdir
4157         cp -p $(which $MULTIOP) $DIR/$tdir/multiop ||
4158                 cp -p multiop $DIR/$tdir/multiop
4159         MULTIOP_PROG=$DIR/$tdir/multiop multiop_bg_pause $TMP/$tfile.junk O_c ||
4160                 error "multiop open $TMP/$tfile.junk failed"
4161         rm $TMP/$tfile.junk     # delete junk file on close (not part of test)
4162         MULTIOP_PID=$!
4163         $TRUNCATE $DIR/$tdir/multiop 0 && error "expected error, got success"
4164         kill -USR1 $MULTIOP_PID || error "kill -USR1 PID $MULTIOP_PID failed"
4165         wait $MULTIOP_PID || error "wait PID $MULTIOP_PID failed"
4166 }
4167 run_test 43b "truncate of file being executed should return -ETXTBSY"
4168
4169 test_43c() {
4170         local testdir="$DIR/$tdir"
4171         test_mkdir $testdir
4172         cp $SHELL $testdir/
4173         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4174                 ( cd $testdir && md5sum -c )
4175 }
4176 run_test 43c "md5sum of copy into lustre"
4177
4178 test_44A() { # was test_44
4179         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4180
4181         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4182         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4183 }
4184 run_test 44A "zero length read from a sparse stripe"
4185
4186 test_44a() {
4187         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4188                 awk '{ print $2 }')
4189         [ -z "$nstripe" ] && skip "can't get stripe info"
4190         [[ $nstripe -gt $OSTCOUNT ]] &&
4191                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4192
4193         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4194                 awk '{ print $2 }')
4195         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4196                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4197                         awk '{ print $2 }')
4198         fi
4199
4200         OFFSETS="0 $((stride/2)) $((stride-1))"
4201         for offset in $OFFSETS; do
4202                 for i in $(seq 0 $((nstripe-1))); do
4203                         local GLOBALOFFSETS=""
4204                         # size in Bytes
4205                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4206                         local myfn=$DIR/d44a-$size
4207                         echo "--------writing $myfn at $size"
4208                         ll_sparseness_write $myfn $size ||
4209                                 error "ll_sparseness_write"
4210                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4211                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4212                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4213
4214                         for j in $(seq 0 $((nstripe-1))); do
4215                                 # size in Bytes
4216                                 size=$((((j + $nstripe )*$stride + $offset)))
4217                                 ll_sparseness_write $myfn $size ||
4218                                         error "ll_sparseness_write"
4219                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4220                         done
4221                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4222                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4223                         rm -f $myfn
4224                 done
4225         done
4226 }
4227 run_test 44a "test sparse pwrite ==============================="
4228
4229 dirty_osc_total() {
4230         tot=0
4231         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4232                 tot=$(($tot + $d))
4233         done
4234         echo $tot
4235 }
4236 do_dirty_record() {
4237         before=`dirty_osc_total`
4238         echo executing "\"$*\""
4239         eval $*
4240         after=`dirty_osc_total`
4241         echo before $before, after $after
4242 }
4243 test_45() {
4244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4245
4246         f="$DIR/f45"
4247         # Obtain grants from OST if it supports it
4248         echo blah > ${f}_grant
4249         stop_writeback
4250         sync
4251         do_dirty_record "echo blah > $f"
4252         [[ $before -eq $after ]] && error "write wasn't cached"
4253         do_dirty_record "> $f"
4254         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4255         do_dirty_record "echo blah > $f"
4256         [[ $before -eq $after ]] && error "write wasn't cached"
4257         do_dirty_record "sync"
4258         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4259         do_dirty_record "echo blah > $f"
4260         [[ $before -eq $after ]] && error "write wasn't cached"
4261         do_dirty_record "cancel_lru_locks osc"
4262         [[ $before -gt $after ]] ||
4263                 error "lock cancellation didn't lower dirty count"
4264         start_writeback
4265 }
4266 run_test 45 "osc io page accounting ============================"
4267
4268 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4269 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4270 # objects offset and an assert hit when an rpc was built with 1023's mapped
4271 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4272 test_46() {
4273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4274
4275         f="$DIR/f46"
4276         stop_writeback
4277         sync
4278         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4279         sync
4280         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4281         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4282         sync
4283         start_writeback
4284 }
4285 run_test 46 "dirtying a previously written page ================"
4286
4287 # test_47 is removed "Device nodes check" is moved to test_28
4288
4289 test_48a() { # bug 2399
4290         [ "$mds1_FSTYPE" = "zfs" ] &&
4291         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4292                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4293
4294         test_mkdir $DIR/$tdir
4295         cd $DIR/$tdir
4296         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4297         test_mkdir $DIR/$tdir
4298         touch foo || error "'touch foo' failed after recreating cwd"
4299         test_mkdir bar
4300         touch .foo || error "'touch .foo' failed after recreating cwd"
4301         test_mkdir .bar
4302         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4303         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4304         cd . || error "'cd .' failed after recreating cwd"
4305         mkdir . && error "'mkdir .' worked after recreating cwd"
4306         rmdir . && error "'rmdir .' worked after recreating cwd"
4307         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4308         cd .. || error "'cd ..' failed after recreating cwd"
4309 }
4310 run_test 48a "Access renamed working dir (should return errors)="
4311
4312 test_48b() { # bug 2399
4313         rm -rf $DIR/$tdir
4314         test_mkdir $DIR/$tdir
4315         cd $DIR/$tdir
4316         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4317         touch foo && error "'touch foo' worked after removing cwd"
4318         mkdir foo && error "'mkdir foo' worked after removing cwd"
4319         touch .foo && error "'touch .foo' worked after removing cwd"
4320         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
4321         ls . > /dev/null && error "'ls .' worked after removing cwd"
4322         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4323         mkdir . && error "'mkdir .' worked after removing cwd"
4324         rmdir . && error "'rmdir .' worked after removing cwd"
4325         ln -s . foo && error "'ln -s .' worked after removing cwd"
4326         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
4327 }
4328 run_test 48b "Access removed working dir (should return errors)="
4329
4330 test_48c() { # bug 2350
4331         #lctl set_param debug=-1
4332         #set -vx
4333         rm -rf $DIR/$tdir
4334         test_mkdir -p $DIR/$tdir/dir
4335         cd $DIR/$tdir/dir
4336         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4337         $TRACE touch foo && error "touch foo worked after removing cwd"
4338         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
4339         touch .foo && error "touch .foo worked after removing cwd"
4340         mkdir .foo && error "mkdir .foo worked after removing cwd"
4341         $TRACE ls . && error "'ls .' worked after removing cwd"
4342         $TRACE ls .. || error "'ls ..' failed after removing cwd"
4343         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
4344         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
4345         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
4346         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
4347 }
4348 run_test 48c "Access removed working subdir (should return errors)"
4349
4350 test_48d() { # bug 2350
4351         #lctl set_param debug=-1
4352         #set -vx
4353         rm -rf $DIR/$tdir
4354         test_mkdir -p $DIR/$tdir/dir
4355         cd $DIR/$tdir/dir
4356         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4357         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4358         $TRACE touch foo && error "'touch foo' worked after removing parent"
4359         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
4360         touch .foo && error "'touch .foo' worked after removing parent"
4361         mkdir .foo && error "mkdir .foo worked after removing parent"
4362         $TRACE ls . && error "'ls .' worked after removing parent"
4363         $TRACE ls .. && error "'ls ..' worked after removing parent"
4364         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
4365         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
4366         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
4367         true
4368 }
4369 run_test 48d "Access removed parent subdir (should return errors)"
4370
4371 test_48e() { # bug 4134
4372         #lctl set_param debug=-1
4373         #set -vx
4374         rm -rf $DIR/$tdir
4375         test_mkdir -p $DIR/$tdir/dir
4376         cd $DIR/$tdir/dir
4377         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4378         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4379         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
4380         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
4381         # On a buggy kernel addition of "touch foo" after cd .. will
4382         # produce kernel oops in lookup_hash_it
4383         touch ../foo && error "'cd ..' worked after recreate parent"
4384         cd $DIR
4385         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
4386 }
4387 run_test 48e "Access to recreated parent subdir (should return errors)"
4388
4389 test_49() { # LU-1030
4390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4391         remote_ost_nodsh && skip "remote OST with nodsh"
4392
4393         # get ost1 size - lustre-OST0000
4394         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
4395                 awk '{ print $4 }')
4396         # write 800M at maximum
4397         [[ $ost1_size -lt 2 ]] && ost1_size=2
4398         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
4399
4400         $LFS setstripe -c 1 -i 0 $DIR/$tfile
4401         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
4402         local dd_pid=$!
4403
4404         # change max_pages_per_rpc while writing the file
4405         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
4406         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
4407         # loop until dd process exits
4408         while ps ax -opid | grep -wq $dd_pid; do
4409                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
4410                 sleep $((RANDOM % 5 + 1))
4411         done
4412         # restore original max_pages_per_rpc
4413         $LCTL set_param $osc1_mppc=$orig_mppc
4414         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
4415 }
4416 run_test 49 "Change max_pages_per_rpc won't break osc extent"
4417
4418 test_50() {
4419         # bug 1485
4420         test_mkdir $DIR/$tdir
4421         cd $DIR/$tdir
4422         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
4423 }
4424 run_test 50 "special situations: /proc symlinks  ==============="
4425
4426 test_51a() {    # was test_51
4427         # bug 1516 - create an empty entry right after ".." then split dir
4428         test_mkdir -c1 $DIR/$tdir
4429         touch $DIR/$tdir/foo
4430         $MCREATE $DIR/$tdir/bar
4431         rm $DIR/$tdir/foo
4432         createmany -m $DIR/$tdir/longfile 201
4433         FNUM=202
4434         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
4435                 $MCREATE $DIR/$tdir/longfile$FNUM
4436                 FNUM=$(($FNUM + 1))
4437                 echo -n "+"
4438         done
4439         echo
4440         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
4441 }
4442 run_test 51a "special situations: split htree with empty entry =="
4443
4444 cleanup_print_lfs_df () {
4445         trap 0
4446         $LFS df
4447         $LFS df -i
4448 }
4449
4450 test_51b() {
4451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4452
4453         local dir=$DIR/$tdir
4454         local nrdirs=$((65536 + 100))
4455
4456         # cleanup the directory
4457         rm -fr $dir
4458
4459         test_mkdir -c1 $dir
4460
4461         $LFS df
4462         $LFS df -i
4463         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
4464         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
4465         [[ $numfree -lt $nrdirs ]] &&
4466                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
4467
4468         # need to check free space for the directories as well
4469         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
4470         numfree=$(( blkfree / $(fs_inode_ksize) ))
4471         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
4472
4473         trap cleanup_print_lfs_df EXIT
4474
4475         # create files
4476         createmany -d $dir/d $nrdirs || {
4477                 unlinkmany $dir/d $nrdirs
4478                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
4479         }
4480
4481         # really created :
4482         nrdirs=$(ls -U $dir | wc -l)
4483
4484         # unlink all but 100 subdirectories, then check it still works
4485         local left=100
4486         local delete=$((nrdirs - left))
4487
4488         $LFS df
4489         $LFS df -i
4490
4491         # for ldiskfs the nlink count should be 1, but this is OSD specific
4492         # and so this is listed for informational purposes only
4493         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
4494         unlinkmany -d $dir/d $delete ||
4495                 error "unlink of first $delete subdirs failed"
4496
4497         echo "nlink between: $(stat -c %h $dir)"
4498         local found=$(ls -U $dir | wc -l)
4499         [ $found -ne $left ] &&
4500                 error "can't find subdirs: found only $found, expected $left"
4501
4502         unlinkmany -d $dir/d $delete $left ||
4503                 error "unlink of second $left subdirs failed"
4504         # regardless of whether the backing filesystem tracks nlink accurately
4505         # or not, the nlink count shouldn't be more than "." and ".." here
4506         local after=$(stat -c %h $dir)
4507         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
4508                 echo "nlink after: $after"
4509
4510         cleanup_print_lfs_df
4511 }
4512 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
4513
4514 test_51d() {
4515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4516         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
4517
4518         test_mkdir $DIR/$tdir
4519         createmany -o $DIR/$tdir/t- 1000
4520         $LFS getstripe $DIR/$tdir > $TMP/$tfile
4521         for N in $(seq 0 $((OSTCOUNT - 1))); do
4522                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
4523                         END { printf("%0.0f", objs) }' $TMP/$tfile)
4524                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
4525                         '($1 == '$N') { objs += 1 } \
4526                         END { printf("%0.0f", objs) }')
4527                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
4528         done
4529         unlinkmany $DIR/$tdir/t- 1000
4530
4531         NLAST=0
4532         for N in $(seq 1 $((OSTCOUNT - 1))); do
4533                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
4534                         error "OST $N has less objects vs OST $NLAST" \
4535                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4536                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
4537                         error "OST $N has less objects vs OST $NLAST" \
4538                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4539
4540                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
4541                         error "OST $N has less #0 objects vs OST $NLAST" \
4542                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4543                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
4544                         error "OST $N has less #0 objects vs OST $NLAST" \
4545                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4546                 NLAST=$N
4547         done
4548         rm -f $TMP/$tfile
4549 }
4550 run_test 51d "check object distribution"
4551
4552 test_51e() {
4553         if [ "$mds1_FSTYPE" != ldiskfs ]; then
4554                 skip_env "ldiskfs only test"
4555         fi
4556
4557         test_mkdir -c1 $DIR/$tdir
4558         test_mkdir -c1 $DIR/$tdir/d0
4559
4560         touch $DIR/$tdir/d0/foo
4561         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
4562                 error "file exceed 65000 nlink limit!"
4563         unlinkmany $DIR/$tdir/d0/f- 65001
4564         return 0
4565 }
4566 run_test 51e "check file nlink limit"
4567
4568 test_51f() {
4569         test_mkdir $DIR/$tdir
4570
4571         local max=100000
4572         local ulimit_old=$(ulimit -n)
4573         local spare=20 # number of spare fd's for scripts/libraries, etc.
4574         local mdt=$($LFS getstripe -m $DIR/$tdir)
4575         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
4576
4577         echo "MDT$mdt numfree=$numfree, max=$max"
4578         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
4579         if [ $((numfree + spare)) -gt $ulimit_old ]; then
4580                 while ! ulimit -n $((numfree + spare)); do
4581                         numfree=$((numfree * 3 / 4))
4582                 done
4583                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
4584         else
4585                 echo "left ulimit at $ulimit_old"
4586         fi
4587
4588         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
4589                 unlinkmany $DIR/$tdir/f $numfree
4590                 error "create+open $numfree files in $DIR/$tdir failed"
4591         }
4592         ulimit -n $ulimit_old
4593
4594         # if createmany exits at 120s there will be fewer than $numfree files
4595         unlinkmany $DIR/$tdir/f $numfree || true
4596 }
4597 run_test 51f "check many open files limit"
4598
4599 test_52a() {
4600         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
4601         test_mkdir $DIR/$tdir
4602         touch $DIR/$tdir/foo
4603         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
4604         echo bar >> $DIR/$tdir/foo || error "append bar failed"
4605         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
4606         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
4607         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
4608                                         error "link worked"
4609         echo foo >> $DIR/$tdir/foo || error "append foo failed"
4610         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
4611         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
4612                                                      error "lsattr"
4613         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
4614         cp -r $DIR/$tdir $TMP/
4615         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
4616 }
4617 run_test 52a "append-only flag test (should return errors)"
4618
4619 test_52b() {
4620         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
4621         test_mkdir $DIR/$tdir
4622         touch $DIR/$tdir/foo
4623         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
4624         cat test > $DIR/$tdir/foo && error "cat test worked"
4625         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
4626         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
4627         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
4628                                         error "link worked"
4629         echo foo >> $DIR/$tdir/foo && error "echo worked"
4630         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
4631         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
4632         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
4633         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
4634                                                         error "lsattr"
4635         chattr -i $DIR/$tdir/foo || error "chattr failed"
4636
4637         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
4638 }
4639 run_test 52b "immutable flag test (should return errors) ======="
4640
4641 test_53() {
4642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4643         remote_mds_nodsh && skip "remote MDS with nodsh"
4644         remote_ost_nodsh && skip "remote OST with nodsh"
4645
4646         local param
4647         local param_seq
4648         local ostname
4649         local mds_last
4650         local mds_last_seq
4651         local ost_last
4652         local ost_last_seq
4653         local ost_last_id
4654         local ostnum
4655         local node
4656         local found=false
4657         local support_last_seq=true
4658
4659         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
4660                 support_last_seq=false
4661
4662         # only test MDT0000
4663         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
4664         local value
4665         for value in $(do_facet $SINGLEMDS \
4666                        $LCTL get_param osc.$mdtosc.prealloc_last_id) ; do
4667                 param=$(echo ${value[0]} | cut -d "=" -f1)
4668                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
4669
4670                 if $support_last_seq; then
4671                         param_seq=$(echo $param |
4672                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
4673                         mds_last_seq=$(do_facet $SINGLEMDS \
4674                                        $LCTL get_param -n $param_seq)
4675                 fi
4676                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
4677
4678                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
4679                 node=$(facet_active_host ost$((ostnum+1)))
4680                 param="obdfilter.$ostname.last_id"
4681                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
4682                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
4683                         ost_last_id=$ost_last
4684
4685                         if $support_last_seq; then
4686                                 ost_last_id=$(echo $ost_last |
4687                                               awk -F':' '{print $2}' |
4688                                               sed -e "s/^0x//g")
4689                                 ost_last_seq=$(echo $ost_last |
4690                                                awk -F':' '{print $1}')
4691                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
4692                         fi
4693
4694                         if [[ $ost_last_id != $mds_last ]]; then
4695                                 error "$ost_last_id != $mds_last"
4696                         else
4697                                 found=true
4698                                 break
4699                         fi
4700                 done
4701         done
4702         $found || error "can not match last_seq/last_id for $mdtosc"
4703         return 0
4704 }
4705 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
4706
4707 test_54a() {
4708         perl -MSocket -e ';' || skip "no Socket perl module installed"
4709
4710         $SOCKETSERVER $DIR/socket ||
4711                 error "$SOCKETSERVER $DIR/socket failed: $?"
4712         $SOCKETCLIENT $DIR/socket ||
4713                 error "$SOCKETCLIENT $DIR/socket failed: $?"
4714         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
4715 }
4716 run_test 54a "unix domain socket test =========================="
4717
4718 test_54b() {
4719         f="$DIR/f54b"
4720         mknod $f c 1 3
4721         chmod 0666 $f
4722         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
4723 }
4724 run_test 54b "char device works in lustre ======================"
4725
4726 find_loop_dev() {
4727         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
4728         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
4729         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
4730
4731         for i in $(seq 3 7); do
4732                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
4733                 LOOPDEV=$LOOPBASE$i
4734                 LOOPNUM=$i
4735                 break
4736         done
4737 }
4738
4739 cleanup_54c() {
4740         local rc=0
4741         loopdev="$DIR/loop54c"
4742
4743         trap 0
4744         $UMOUNT $DIR/$tdir || rc=$?
4745         losetup -d $loopdev || true
4746         losetup -d $LOOPDEV || true
4747         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
4748         return $rc
4749 }
4750
4751 test_54c() {
4752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4753
4754         loopdev="$DIR/loop54c"
4755
4756         find_loop_dev
4757         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
4758         trap cleanup_54c EXIT
4759         mknod $loopdev b 7 $LOOPNUM
4760         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
4761         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
4762         losetup $loopdev $DIR/$tfile ||
4763                 error "can't set up $loopdev for $DIR/$tfile"
4764         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
4765         test_mkdir $DIR/$tdir
4766         mount -t ext2 $loopdev $DIR/$tdir ||
4767                 error "error mounting $loopdev on $DIR/$tdir"
4768         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
4769                 error "dd write"
4770         df $DIR/$tdir
4771         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
4772                 error "dd read"
4773         cleanup_54c
4774 }
4775 run_test 54c "block device works in lustre ====================="
4776
4777 test_54d() {
4778         f="$DIR/f54d"
4779         string="aaaaaa"
4780         mknod $f p
4781         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
4782 }
4783 run_test 54d "fifo device works in lustre ======================"
4784
4785 test_54e() {
4786         f="$DIR/f54e"
4787         string="aaaaaa"
4788         cp -aL /dev/console $f
4789         echo $string > $f || error "echo $string to $f failed"
4790 }
4791 run_test 54e "console/tty device works in lustre ======================"
4792
4793 test_56a() {
4794         local numfiles=3
4795         local dir=$DIR/$tdir
4796
4797         rm -rf $dir
4798         test_mkdir -p $dir/dir
4799         for i in $(seq $numfiles); do
4800                 touch $dir/file$i
4801                 touch $dir/dir/file$i
4802         done
4803
4804         local numcomp=$($LFS getstripe --component-count $dir)
4805
4806         [[ $numcomp == 0 ]] && numcomp=1
4807
4808         # test lfs getstripe with --recursive
4809         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
4810
4811         [[ $filenum -eq $((numfiles * 2)) ]] ||
4812                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
4813         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
4814         [[ $filenum -eq $numfiles ]] ||
4815                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
4816         echo "$LFS getstripe showed obdidx or l_ost_idx"
4817
4818         # test lfs getstripe with file instead of dir
4819         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
4820         [[ $filenum -eq 1 ]] ||
4821                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
4822         echo "$LFS getstripe file1 passed"
4823
4824         #test lfs getstripe with --verbose
4825         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
4826         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
4827                 error "$LFS getstripe --verbose $dir: "\
4828                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
4829         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
4830                 error "$LFS getstripe $dir: showed lmm_magic"
4831
4832         #test lfs getstripe with -v prints lmm_fid
4833         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
4834         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
4835                 error "$LFS getstripe -v $dir: "\
4836                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
4837         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
4838                 error "$LFS getstripe $dir: showed lmm_fid by default"
4839         echo "$LFS getstripe --verbose passed"
4840
4841         #check for FID information
4842         local fid1=$($LFS getstripe --fid $dir/file1)
4843         local fid2=$($LFS getstripe --verbose $dir/file1 |
4844                      awk '/lmm_fid: / { print $2; exit; }')
4845         local fid3=$($LFS path2fid $dir/file1)
4846
4847         [ "$fid1" != "$fid2" ] &&
4848                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
4849         [ "$fid1" != "$fid3" ] &&
4850                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
4851         echo "$LFS getstripe --fid passed"
4852
4853         #test lfs getstripe with --obd
4854         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
4855                 error "$LFS getstripe --obd wrong_uuid: should return error"
4856
4857         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4858
4859         local ostidx=1
4860         local obduuid=$(ostuuid_from_index $ostidx)
4861         local found=$($LFS getstripe -r --obd $obduuid $dir |
4862                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
4863
4864         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
4865         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
4866                 ((filenum--))
4867         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
4868                 ((filenum--))
4869
4870         [[ $found -eq $filenum ]] ||
4871                 error "$LFS getstripe --obd: found $found expect $filenum"
4872         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
4873                 sed '/^[         ]*'${ostidx}'[  ]/d' |
4874                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
4875                 error "$LFS getstripe --obd: should not show file on other obd"
4876         echo "$LFS getstripe --obd passed"
4877 }
4878 run_test 56a "check $LFS getstripe"
4879
4880 test_56b() {
4881         local dir=$DIR/$tdir
4882         local numdirs=3
4883
4884         test_mkdir $dir
4885         for i in $(seq $numdirs); do
4886                 test_mkdir $dir/dir$i
4887         done
4888
4889         # test lfs getdirstripe default mode is non-recursion, which is
4890         # different from lfs getstripe
4891         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
4892
4893         [[ $dircnt -eq 1 ]] ||
4894                 error "$LFS getdirstripe: found $dircnt, not 1"
4895         dircnt=$($LFS getdirstripe --recursive $dir |
4896                 grep -c lmv_stripe_count)
4897         [[ $dircnt -eq $((numdirs + 1)) ]] ||
4898                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
4899 }
4900 run_test 56b "check $LFS getdirstripe"
4901
4902 test_56c() {
4903         remote_ost_nodsh && skip "remote OST with nodsh"
4904
4905         local ost_idx=0
4906         local ost_name=$(ostname_from_index $ost_idx)
4907         local old_status=$(ost_dev_status $ost_idx)
4908
4909         [[ -z "$old_status" ]] ||
4910                 skip_env "OST $ost_name is in $old_status status"
4911
4912         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
4913         sleep_maxage
4914
4915         local new_status=$(ost_dev_status $ost_idx)
4916
4917         [[ "$new_status" = "D" ]] ||
4918                 error "OST $ost_name is in status of '$new_status', not 'D'"
4919
4920         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
4921         sleep_maxage
4922
4923         new_status=$(ost_dev_status $ost_idx)
4924         [[ -z "$new_status" ]] ||
4925                 error "OST $ost_name is in status of '$new_status', not ''"
4926 }
4927 run_test 56c "check 'lfs df' showing device status"
4928
4929 NUMFILES=3
4930 NUMDIRS=3
4931 setup_56() {
4932         local local_tdir="$1"
4933         local local_numfiles="$2"
4934         local local_numdirs="$3"
4935         local dir_params="$4"
4936         local dir_stripe_params="$5"
4937
4938         if [ ! -d "$local_tdir" ] ; then
4939                 test_mkdir -p $dir_stripe_params $local_tdir
4940                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
4941                 for i in $(seq $local_numfiles) ; do
4942                         touch $local_tdir/file$i
4943                 done
4944                 for i in $(seq $local_numdirs) ; do
4945                         test_mkdir $dir_stripe_params $local_tdir/dir$i
4946                         for j in $(seq $local_numfiles) ; do
4947                                 touch $local_tdir/dir$i/file$j
4948                         done
4949                 done
4950         fi
4951 }
4952
4953 setup_56_special() {
4954         local local_tdir=$1
4955         local local_numfiles=$2
4956         local local_numdirs=$3
4957
4958         setup_56 $local_tdir $local_numfiles $local_numdirs
4959
4960         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
4961                 for i in $(seq $local_numfiles) ; do
4962                         mknod $local_tdir/loop${i}b b 7 $i
4963                         mknod $local_tdir/null${i}c c 1 3
4964                         ln -s $local_tdir/file1 $local_tdir/link${i}
4965                 done
4966                 for i in $(seq $local_numdirs) ; do
4967                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
4968                         mknod $local_tdir/dir$i/null${i}c c 1 3
4969                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
4970                 done
4971         fi
4972 }
4973
4974 test_56g() {
4975         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
4976         local expected=$(($NUMDIRS + 2))
4977
4978         setup_56 $dir $NUMFILES $NUMDIRS
4979
4980         # test lfs find with -name
4981         for i in $(seq $NUMFILES) ; do
4982                 local nums=$($LFS find -name "*$i" $dir | wc -l)
4983
4984                 [ $nums -eq $expected ] ||
4985                         error "lfs find -name '*$i' $dir wrong: "\
4986                               "found $nums, expected $expected"
4987         done
4988 }
4989 run_test 56g "check lfs find -name"
4990
4991 test_56h() {
4992         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
4993         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
4994
4995         setup_56 $dir $NUMFILES $NUMDIRS
4996
4997         # test lfs find with ! -name
4998         for i in $(seq $NUMFILES) ; do
4999                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5000
5001                 [ $nums -eq $expected ] ||
5002                         error "lfs find ! -name '*$i' $dir wrong: "\
5003                               "found $nums, expected $expected"
5004         done
5005 }
5006 run_test 56h "check lfs find ! -name"
5007
5008 test_56i() {
5009         local dir=$DIR/$tdir
5010
5011         test_mkdir $dir
5012
5013         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5014         local out=$($cmd)
5015
5016         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5017 }
5018 run_test 56i "check 'lfs find -ost UUID' skips directories"
5019
5020 test_56j() {
5021         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5022
5023         setup_56_special $dir $NUMFILES $NUMDIRS
5024
5025         local expected=$((NUMDIRS + 1))
5026         local cmd="$LFS find -type d $dir"
5027         local nums=$($cmd | wc -l)
5028
5029         [ $nums -eq $expected ] ||
5030                 error "'$cmd' wrong: found $nums, expected $expected"
5031 }
5032 run_test 56j "check lfs find -type d"
5033
5034 test_56k() {
5035         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5036
5037         setup_56_special $dir $NUMFILES $NUMDIRS
5038
5039         local expected=$(((NUMDIRS + 1) * NUMFILES))
5040         local cmd="$LFS find -type f $dir"
5041         local nums=$($cmd | wc -l)
5042
5043         [ $nums -eq $expected ] ||
5044                 error "'$cmd' wrong: found $nums, expected $expected"
5045 }
5046 run_test 56k "check lfs find -type f"
5047
5048 test_56l() {
5049         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5050
5051         setup_56_special $dir $NUMFILES $NUMDIRS
5052
5053         local expected=$((NUMDIRS + NUMFILES))
5054         local cmd="$LFS find -type b $dir"
5055         local nums=$($cmd | wc -l)
5056
5057         [ $nums -eq $expected ] ||
5058                 error "'$cmd' wrong: found $nums, expected $expected"
5059 }
5060 run_test 56l "check lfs find -type b"
5061
5062 test_56m() {
5063         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5064
5065         setup_56_special $dir $NUMFILES $NUMDIRS
5066
5067         local expected=$((NUMDIRS + NUMFILES))
5068         local cmd="$LFS find -type c $dir"
5069         local nums=$($cmd | wc -l)
5070         [ $nums -eq $expected ] ||
5071                 error "'$cmd' wrong: found $nums, expected $expected"
5072 }
5073 run_test 56m "check lfs find -type c"
5074
5075 test_56n() {
5076         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5077         setup_56_special $dir $NUMFILES $NUMDIRS
5078
5079         local expected=$((NUMDIRS + NUMFILES))
5080         local cmd="$LFS find -type l $dir"
5081         local nums=$($cmd | wc -l)
5082
5083         [ $nums -eq $expected ] ||
5084                 error "'$cmd' wrong: found $nums, expected $expected"
5085 }
5086 run_test 56n "check lfs find -type l"
5087
5088 test_56o() {
5089         local dir=$DIR/$tdir
5090
5091         setup_56 $dir $NUMFILES $NUMDIRS
5092         utime $dir/file1 > /dev/null || error "utime (1)"
5093         utime $dir/file2 > /dev/null || error "utime (2)"
5094         utime $dir/dir1 > /dev/null || error "utime (3)"
5095         utime $dir/dir2 > /dev/null || error "utime (4)"
5096         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5097         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5098
5099         local expected=4
5100         local nums=$($LFS find -mtime +0 $dir | wc -l)
5101
5102         [ $nums -eq $expected ] ||
5103                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5104
5105         expected=12
5106         cmd="$LFS find -mtime 0 $dir"
5107         nums=$($cmd | wc -l)
5108         [ $nums -eq $expected ] ||
5109                 error "'$cmd' wrong: found $nums, expected $expected"
5110 }
5111 run_test 56o "check lfs find -mtime for old files"
5112
5113 test_56ob() {
5114         local dir=$DIR/$tdir
5115         local expected=1
5116         local count=0
5117
5118         # just to make sure there is something that won't be found
5119         test_mkdir $dir
5120         touch $dir/$tfile.now
5121
5122         for age in year week day hour min; do
5123                 count=$((count + 1))
5124
5125                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5126                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5127                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5128
5129                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5130                 local nums=$($cmd | wc -l)
5131                 [ $nums -eq $expected ] ||
5132                         error "'$cmd' wrong: found $nums, expected $expected"
5133
5134                 cmd="$LFS find $dir -atime $count${age:0:1}"
5135                 nums=$($cmd | wc -l)
5136                 [ $nums -eq $expected ] ||
5137                         error "'$cmd' wrong: found $nums, expected $expected"
5138         done
5139
5140         sleep 2
5141         cmd="$LFS find $dir -ctime +1s -type f"
5142         nums=$($cmd | wc -l)
5143         (( $nums == $count * 2 + 1)) ||
5144                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5145 }
5146 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5147
5148 test_56p() {
5149         [ $RUNAS_ID -eq $UID ] &&
5150                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5151
5152         local dir=$DIR/$tdir
5153
5154         setup_56 $dir $NUMFILES $NUMDIRS
5155         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5156
5157         local expected=$NUMFILES
5158         local cmd="$LFS find -uid $RUNAS_ID $dir"
5159         local nums=$($cmd | wc -l)
5160
5161         [ $nums -eq $expected ] ||
5162                 error "'$cmd' wrong: found $nums, expected $expected"
5163
5164         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5165         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5166         nums=$($cmd | wc -l)
5167         [ $nums -eq $expected ] ||
5168                 error "'$cmd' wrong: found $nums, expected $expected"
5169 }
5170 run_test 56p "check lfs find -uid and ! -uid"
5171
5172 test_56q() {
5173         [ $RUNAS_ID -eq $UID ] &&
5174                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5175
5176         local dir=$DIR/$tdir
5177
5178         setup_56 $dir $NUMFILES $NUMDIRS
5179         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5180
5181         local expected=$NUMFILES
5182         local cmd="$LFS find -gid $RUNAS_GID $dir"
5183         local nums=$($cmd | wc -l)
5184
5185         [ $nums -eq $expected ] ||
5186                 error "'$cmd' wrong: found $nums, expected $expected"
5187
5188         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5189         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5190         nums=$($cmd | wc -l)
5191         [ $nums -eq $expected ] ||
5192                 error "'$cmd' wrong: found $nums, expected $expected"
5193 }
5194 run_test 56q "check lfs find -gid and ! -gid"
5195
5196 test_56r() {
5197         local dir=$DIR/$tdir
5198
5199         setup_56 $dir $NUMFILES $NUMDIRS
5200
5201         local expected=12
5202         local cmd="$LFS find -size 0 -type f $dir"
5203         local nums=$($cmd | wc -l)
5204
5205         [ $nums -eq $expected ] ||
5206                 error "'$cmd' wrong: found $nums, expected $expected"
5207         expected=0
5208         cmd="$LFS find ! -size 0 -type f $dir"
5209         nums=$($cmd | wc -l)
5210         [ $nums -eq $expected ] ||
5211                 error "'$cmd' wrong: found $nums, expected $expected"
5212         echo "test" > $dir/$tfile
5213         echo "test2" > $dir/$tfile.2 && sync
5214         expected=1
5215         cmd="$LFS find -size 5 -type f $dir"
5216         nums=$($cmd | wc -l)
5217         [ $nums -eq $expected ] ||
5218                 error "'$cmd' wrong: found $nums, expected $expected"
5219         expected=1
5220         cmd="$LFS find -size +5 -type f $dir"
5221         nums=$($cmd | wc -l)
5222         [ $nums -eq $expected ] ||
5223                 error "'$cmd' wrong: found $nums, expected $expected"
5224         expected=2
5225         cmd="$LFS find -size +0 -type f $dir"
5226         nums=$($cmd | wc -l)
5227         [ $nums -eq $expected ] ||
5228                 error "'$cmd' wrong: found $nums, expected $expected"
5229         expected=2
5230         cmd="$LFS find ! -size -5 -type f $dir"
5231         nums=$($cmd | wc -l)
5232         [ $nums -eq $expected ] ||
5233                 error "'$cmd' wrong: found $nums, expected $expected"
5234         expected=12
5235         cmd="$LFS find -size -5 -type f $dir"
5236         nums=$($cmd | wc -l)
5237         [ $nums -eq $expected ] ||
5238                 error "'$cmd' wrong: found $nums, expected $expected"
5239 }
5240 run_test 56r "check lfs find -size works"
5241
5242 test_56s() { # LU-611 #LU-9369
5243         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
5244
5245         local dir=$DIR/$tdir
5246         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
5247
5248         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
5249         for i in $(seq $NUMDIRS); do
5250                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
5251         done
5252
5253         local expected=$NUMDIRS
5254         local cmd="$LFS find -c $OSTCOUNT $dir"
5255         local nums=$($cmd | wc -l)
5256
5257         [ $nums -eq $expected ] || {
5258                 $LFS getstripe -R $dir
5259                 error "'$cmd' wrong: found $nums, expected $expected"
5260         }
5261
5262         expected=$((NUMDIRS + onestripe))
5263         cmd="$LFS find -stripe-count +0 -type f $dir"
5264         nums=$($cmd | wc -l)
5265         [ $nums -eq $expected ] || {
5266                 $LFS getstripe -R $dir
5267                 error "'$cmd' wrong: found $nums, expected $expected"
5268         }
5269
5270         expected=$onestripe
5271         cmd="$LFS find -stripe-count 1 -type f $dir"
5272         nums=$($cmd | wc -l)
5273         [ $nums -eq $expected ] || {
5274                 $LFS getstripe -R $dir
5275                 error "'$cmd' wrong: found $nums, expected $expected"
5276         }
5277
5278         cmd="$LFS find -stripe-count -2 -type f $dir"
5279         nums=$($cmd | wc -l)
5280         [ $nums -eq $expected ] || {
5281                 $LFS getstripe -R $dir
5282                 error "'$cmd' wrong: found $nums, expected $expected"
5283         }
5284
5285         expected=0
5286         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
5287         nums=$($cmd | wc -l)
5288         [ $nums -eq $expected ] || {
5289                 $LFS getstripe -R $dir
5290                 error "'$cmd' wrong: found $nums, expected $expected"
5291         }
5292 }
5293 run_test 56s "check lfs find -stripe-count works"
5294
5295 test_56t() { # LU-611 #LU-9369
5296         local dir=$DIR/$tdir
5297
5298         setup_56 $dir 0 $NUMDIRS
5299         for i in $(seq $NUMDIRS); do
5300                 $LFS setstripe -S 8M $dir/dir$i/$tfile
5301         done
5302
5303         local expected=$NUMDIRS
5304         local cmd="$LFS find -S 8M $dir"
5305         local nums=$($cmd | wc -l)
5306
5307         [ $nums -eq $expected ] || {
5308                 $LFS getstripe -R $dir
5309                 error "'$cmd' wrong: found $nums, expected $expected"
5310         }
5311         rm -rf $dir
5312
5313         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
5314
5315         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
5316
5317         expected=$(((NUMDIRS + 1) * NUMFILES))
5318         cmd="$LFS find -stripe-size 512k -type f $dir"
5319         nums=$($cmd | wc -l)
5320         [ $nums -eq $expected ] ||
5321                 error "'$cmd' wrong: found $nums, expected $expected"
5322
5323         cmd="$LFS find -stripe-size +320k -type f $dir"
5324         nums=$($cmd | wc -l)
5325         [ $nums -eq $expected ] ||
5326                 error "'$cmd' wrong: found $nums, expected $expected"
5327
5328         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
5329         cmd="$LFS find -stripe-size +200k -type f $dir"
5330         nums=$($cmd | wc -l)
5331         [ $nums -eq $expected ] ||
5332                 error "'$cmd' wrong: found $nums, expected $expected"
5333
5334         cmd="$LFS find -stripe-size -640k -type f $dir"
5335         nums=$($cmd | wc -l)
5336         [ $nums -eq $expected ] ||
5337                 error "'$cmd' wrong: found $nums, expected $expected"
5338
5339         expected=4
5340         cmd="$LFS find -stripe-size 256k -type f $dir"
5341         nums=$($cmd | wc -l)
5342         [ $nums -eq $expected ] ||
5343                 error "'$cmd' wrong: found $nums, expected $expected"
5344
5345         cmd="$LFS find -stripe-size -320k -type f $dir"
5346         nums=$($cmd | wc -l)
5347         [ $nums -eq $expected ] ||
5348                 error "'$cmd' wrong: found $nums, expected $expected"
5349
5350         expected=0
5351         cmd="$LFS find -stripe-size 1024k -type f $dir"
5352         nums=$($cmd | wc -l)
5353         [ $nums -eq $expected ] ||
5354                 error "'$cmd' wrong: found $nums, expected $expected"
5355 }
5356 run_test 56t "check lfs find -stripe-size works"
5357
5358 test_56u() { # LU-611
5359         local dir=$DIR/$tdir
5360
5361         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
5362
5363         if [[ $OSTCOUNT -gt 1 ]]; then
5364                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
5365                 onestripe=4
5366         else
5367                 onestripe=0
5368         fi
5369
5370         local expected=$(((NUMDIRS + 1) * NUMFILES))
5371         local cmd="$LFS find -stripe-index 0 -type f $dir"
5372         local nums=$($cmd | wc -l)
5373
5374         [ $nums -eq $expected ] ||
5375                 error "'$cmd' wrong: found $nums, expected $expected"
5376
5377         expected=$onestripe
5378         cmd="$LFS find -stripe-index 1 -type f $dir"
5379         nums=$($cmd | wc -l)
5380         [ $nums -eq $expected ] ||
5381                 error "'$cmd' wrong: found $nums, expected $expected"
5382
5383         cmd="$LFS find ! -stripe-index 0 -type f $dir"
5384         nums=$($cmd | wc -l)
5385         [ $nums -eq $expected ] ||
5386                 error "'$cmd' wrong: found $nums, expected $expected"
5387
5388         expected=0
5389         # This should produce an error and not return any files
5390         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
5391         nums=$($cmd 2>/dev/null | wc -l)
5392         [ $nums -eq $expected ] ||
5393                 error "'$cmd' wrong: found $nums, expected $expected"
5394
5395         if [[ $OSTCOUNT -gt 1 ]]; then
5396                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
5397                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
5398                 nums=$($cmd | wc -l)
5399                 [ $nums -eq $expected ] ||
5400                         error "'$cmd' wrong: found $nums, expected $expected"
5401         fi
5402 }
5403 run_test 56u "check lfs find -stripe-index works"
5404
5405 test_56v() {
5406         local mdt_idx=0
5407         local dir=$DIR/$tdir
5408
5409         setup_56 $dir $NUMFILES $NUMDIRS
5410
5411         UUID=$(mdtuuid_from_index $mdt_idx $dir)
5412         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
5413
5414         for file in $($LFS find -m $UUID $dir); do
5415                 file_midx=$($LFS getstripe -m $file)
5416                 [ $file_midx -eq $mdt_idx ] ||
5417                         error "lfs find -m $UUID != getstripe -m $file_midx"
5418         done
5419 }
5420 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
5421
5422 test_56w() {
5423         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5425
5426         local dir=$DIR/$tdir
5427
5428         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
5429
5430         local stripe_size=$($LFS getstripe -S -d $dir) ||
5431                 error "$LFS getstripe -S -d $dir failed"
5432         stripe_size=${stripe_size%% *}
5433
5434         local file_size=$((stripe_size * OSTCOUNT))
5435         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
5436         local required_space=$((file_num * file_size))
5437         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
5438                            head -n1)
5439         [[ $free_space -le $((required_space / 1024)) ]] &&
5440                 skip_env "need $required_space, have $free_space kbytes"
5441
5442         local dd_bs=65536
5443         local dd_count=$((file_size / dd_bs))
5444
5445         # write data into the files
5446         local i
5447         local j
5448         local file
5449
5450         for i in $(seq $NUMFILES); do
5451                 file=$dir/file$i
5452                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5453                         error "write data into $file failed"
5454         done
5455         for i in $(seq $NUMDIRS); do
5456                 for j in $(seq $NUMFILES); do
5457                         file=$dir/dir$i/file$j
5458                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5459                                 error "write data into $file failed"
5460                 done
5461         done
5462
5463         # $LFS_MIGRATE will fail if hard link migration is unsupported
5464         if [[ $(lustre_version_code mds1) -gt $(version_code 2.5.55) ]]; then
5465                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
5466                         error "creating links to $dir/dir1/file1 failed"
5467         fi
5468
5469         local expected=-1
5470
5471         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
5472
5473         # lfs_migrate file
5474         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
5475
5476         echo "$cmd"
5477         eval $cmd || error "$cmd failed"
5478
5479         check_stripe_count $dir/file1 $expected
5480
5481         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
5482         then
5483                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
5484                 # OST 1 if it is on OST 0. This file is small enough to
5485                 # be on only one stripe.
5486                 file=$dir/migr_1_ost
5487                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
5488                         error "write data into $file failed"
5489                 local obdidx=$($LFS getstripe -i $file)
5490                 local oldmd5=$(md5sum $file)
5491                 local newobdidx=0
5492
5493                 [[ $obdidx -eq 0 ]] && newobdidx=1
5494                 cmd="$LFS migrate -i $newobdidx $file"
5495                 echo $cmd
5496                 eval $cmd || error "$cmd failed"
5497
5498                 local realobdix=$($LFS getstripe -i $file)
5499                 local newmd5=$(md5sum $file)
5500
5501                 [[ $newobdidx -ne $realobdix ]] &&
5502                         error "new OST is different (was=$obdidx, "\
5503                               "wanted=$newobdidx, got=$realobdix)"
5504                 [[ "$oldmd5" != "$newmd5" ]] &&
5505                         error "md5sum differ: $oldmd5, $newmd5"
5506         fi
5507
5508         # lfs_migrate dir
5509         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
5510         echo "$cmd"
5511         eval $cmd || error "$cmd failed"
5512
5513         for j in $(seq $NUMFILES); do
5514                 check_stripe_count $dir/dir1/file$j $expected
5515         done
5516
5517         # lfs_migrate works with lfs find
5518         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
5519              $LFS_MIGRATE -y -c $expected"
5520         echo "$cmd"
5521         eval $cmd || error "$cmd failed"
5522
5523         for i in $(seq 2 $NUMFILES); do
5524                 check_stripe_count $dir/file$i $expected
5525         done
5526         for i in $(seq 2 $NUMDIRS); do
5527                 for j in $(seq $NUMFILES); do
5528                 check_stripe_count $dir/dir$i/file$j $expected
5529                 done
5530         done
5531 }
5532 run_test 56w "check lfs_migrate -c stripe_count works"
5533
5534 test_56wb() {
5535         local file1=$DIR/$tdir/file1
5536         local create_pool=false
5537         local initial_pool=$($LFS getstripe -p $DIR)
5538         local pool_list=()
5539         local pool=""
5540
5541         echo -n "Creating test dir..."
5542         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5543         echo "done."
5544
5545         echo -n "Creating test file..."
5546         touch $file1 || error "cannot create file"
5547         echo "done."
5548
5549         echo -n "Detecting existing pools..."
5550         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
5551
5552         if [ ${#pool_list[@]} -gt 0 ]; then
5553                 echo "${pool_list[@]}"
5554                 for thispool in "${pool_list[@]}"; do
5555                         if [[ -z "$initial_pool" ||
5556                               "$initial_pool" != "$thispool" ]]; then
5557                                 pool="$thispool"
5558                                 echo "Using existing pool '$pool'"
5559                                 break
5560                         fi
5561                 done
5562         else
5563                 echo "none detected."
5564         fi
5565         if [ -z "$pool" ]; then
5566                 pool=${POOL:-testpool}
5567                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
5568                 echo -n "Creating pool '$pool'..."
5569                 create_pool=true
5570                 pool_add $pool &> /dev/null ||
5571                         error "pool_add failed"
5572                 echo "done."
5573
5574                 echo -n "Adding target to pool..."
5575                 pool_add_targets $pool 0 0 1 &> /dev/null ||
5576                         error "pool_add_targets failed"
5577                 echo "done."
5578         fi
5579
5580         echo -n "Setting pool using -p option..."
5581         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
5582                 error "migrate failed rc = $?"
5583         echo "done."
5584
5585         echo -n "Verifying test file is in pool after migrating..."
5586         [ "$($LFS getstripe -p $file1)" = $pool ] ||
5587                 error "file was not migrated to pool $pool"
5588         echo "done."
5589
5590         echo -n "Removing test file from pool '$pool'..."
5591         $LFS migrate $file1 &> /dev/null ||
5592                 error "cannot remove from pool"
5593         [ "$($LFS getstripe -p $file1)" ] &&
5594                 error "pool still set"
5595         echo "done."
5596
5597         echo -n "Setting pool using --pool option..."
5598         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
5599                 error "migrate failed rc = $?"
5600         echo "done."
5601
5602         # Clean up
5603         rm -f $file1
5604         if $create_pool; then
5605                 destroy_test_pools 2> /dev/null ||
5606                         error "destroy test pools failed"
5607         fi
5608 }
5609 run_test 56wb "check lfs_migrate pool support"
5610
5611 test_56wc() {
5612         local file1="$DIR/$tdir/file1"
5613
5614         echo -n "Creating test dir..."
5615         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5616         local def_stripe_size=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
5617         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
5618                 error "cannot set stripe"
5619         echo "done"
5620
5621         echo -n "Setting initial stripe for test file..."
5622         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
5623                 error "cannot set stripe"
5624         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
5625                 error "stripe size not set"
5626         echo "done."
5627
5628         # File currently set to -S 512K -c 1
5629
5630         # Ensure -c and -S options are rejected when -R is set
5631         echo -n "Verifying incompatible options are detected..."
5632         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
5633                 error "incompatible -c and -R options not detected"
5634         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
5635                 error "incompatible -S and -R options not detected"
5636         echo "done."
5637
5638         # Ensure unrecognized options are passed through to 'lfs migrate'
5639         echo -n "Verifying -S option is passed through to lfs migrate..."
5640         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
5641                 error "migration failed"
5642         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
5643                 error "file was not restriped"
5644         echo "done."
5645
5646         # File currently set to -S 1M -c 1
5647
5648         # Ensure long options are supported
5649         echo -n "Verifying long options supported..."
5650         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
5651                 error "long option without argument not supported"
5652         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
5653                 error "long option with argument not supported"
5654         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
5655                 error "file not restriped with --stripe-size option"
5656         echo "done."
5657
5658         # File currently set to -S 512K -c 1
5659
5660         if [ "$OSTCOUNT" -gt 1 ]; then
5661                 echo -n "Verifying explicit stripe count can be set..."
5662                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
5663                         error "migrate failed"
5664                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
5665                         error "file not restriped to explicit count"
5666                 echo "done."
5667         fi
5668
5669         # File currently set to -S 512K -c 1 or -S 512K -c 2
5670
5671         # Ensure parent striping is used if -R is set, and no stripe
5672         # count or size is specified
5673         echo -n "Setting stripe for parent directory..."
5674         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
5675                 error "cannot set stripe"
5676         echo "done."
5677
5678         echo -n "Verifying restripe option uses parent stripe settings..."
5679         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
5680                 error "migrate failed"
5681         [ $($LFS getstripe -S "$file1") -eq $def_stripe_size ] ||
5682                 error "file not restriped to parent settings"
5683         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
5684                 error "file not restriped to parent settings"
5685         echo "done."
5686
5687         # File currently set to -S 1M -c 1
5688
5689         # Ensure striping is preserved if -R is not set, and no stripe
5690         # count or size is specified
5691         echo -n "Verifying striping size preserved when not specified..."
5692         local orig_stripe_size=$($LFS getstripe -S "$file1" 2>/dev/null)
5693         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
5694                 error "cannot set stripe on parent directory"
5695         $LFS_MIGRATE -y "$file1" &> /dev/null ||
5696                 error "migrate failed"
5697         [ $($LFS getstripe -S "$file1") -eq $orig_stripe_size ] ||
5698                 error "file was restriped"
5699         echo "done."
5700
5701         # Ensure file name properly detected when final option has no argument
5702         echo -n "Verifying file name properly detected..."
5703         $LFS_MIGRATE -y "$file1" &> /dev/null ||
5704                 error "file name interpreted as option argument"
5705         echo "done."
5706
5707         # Clean up
5708         rm -f "$file1"
5709 }
5710 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
5711
5712 test_56wd() {
5713         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5714
5715         local file1=$DIR/$tdir/file1
5716
5717         echo -n "Creating test dir..."
5718         test_mkdir $DIR/$tdir || error "cannot create dir"
5719         echo "done."
5720
5721         echo -n "Creating test file..."
5722         touch $file1
5723         echo "done."
5724
5725         # Ensure 'lfs migrate' will fail by using a non-existent option,
5726         # and make sure rsync is not called to recover
5727         echo -n "Make sure --no-rsync option works..."
5728         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
5729                 grep -q 'refusing to fall back to rsync' ||
5730                 error "rsync was called with --no-rsync set"
5731         echo "done."
5732
5733         # Ensure rsync is called without trying 'lfs migrate' first
5734         echo -n "Make sure --rsync option works..."
5735         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
5736                 grep -q 'falling back to rsync' &&
5737                 error "lfs migrate was called with --rsync set"
5738         echo "done."
5739
5740         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
5741         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
5742                 grep -q 'at the same time' ||
5743                 error "--rsync and --no-rsync accepted concurrently"
5744         echo "done."
5745
5746         # Clean up
5747         rm -f $file1
5748 }
5749 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
5750
5751 test_56x() {
5752         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5753         check_swap_layouts_support
5754
5755         local dir=$DIR/$tdir
5756         local ref1=/etc/passwd
5757         local file1=$dir/file1
5758
5759         test_mkdir $dir || error "creating dir $dir"
5760         $LFS setstripe -c 2 $file1
5761         cp $ref1 $file1
5762         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
5763         stripe=$($LFS getstripe -c $file1)
5764         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
5765         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
5766
5767         # clean up
5768         rm -f $file1
5769 }
5770 run_test 56x "lfs migration support"
5771
5772 test_56xa() {
5773         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5774         check_swap_layouts_support
5775
5776         local dir=$DIR/$tdir/$testnum
5777
5778         test_mkdir -p $dir
5779
5780         local ref1=/etc/passwd
5781         local file1=$dir/file1
5782
5783         $LFS setstripe -c 2 $file1
5784         cp $ref1 $file1
5785         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
5786
5787         local stripe=$($LFS getstripe -c $file1)
5788
5789         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
5790         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
5791
5792         # clean up
5793         rm -f $file1
5794 }
5795 run_test 56xa "lfs migration --block support"
5796
5797 check_migrate_links() {
5798         local dir="$1"
5799         local file1="$dir/file1"
5800         local begin="$2"
5801         local count="$3"
5802         local total_count=$(($begin + $count - 1))
5803         local symlink_count=10
5804         local uniq_count=10
5805
5806         if [ ! -f "$file1" ]; then
5807                 echo -n "creating initial file..."
5808                 $LFS setstripe -c 1 -S "512k" "$file1" ||
5809                         error "cannot setstripe initial file"
5810                 echo "done"
5811
5812                 echo -n "creating symlinks..."
5813                 for s in $(seq 1 $symlink_count); do
5814                         ln -s "$file1" "$dir/slink$s" ||
5815                                 error "cannot create symlinks"
5816                 done
5817                 echo "done"
5818
5819                 echo -n "creating nonlinked files..."
5820                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
5821                         error "cannot create nonlinked files"
5822                 echo "done"
5823         fi
5824
5825         # create hard links
5826         if [ ! -f "$dir/file$total_count" ]; then
5827                 echo -n "creating hard links $begin:$total_count..."
5828                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
5829                         /dev/null || error "cannot create hard links"
5830                 echo "done"
5831         fi
5832
5833         echo -n "checking number of hard links listed in xattrs..."
5834         local fid=$($LFS getstripe -F "$file1")
5835         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
5836
5837         echo "${#paths[*]}"
5838         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
5839                         skip "hard link list has unexpected size, skipping test"
5840         fi
5841         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
5842                         error "link names should exceed xattrs size"
5843         fi
5844
5845         echo -n "migrating files..."
5846         local migrate_out=$($LFS_MIGRATE -y -S '1m' $dir)
5847         local rc=$?
5848         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
5849         echo "done"
5850
5851         # make sure all links have been properly migrated
5852         echo -n "verifying files..."
5853         fid=$($LFS getstripe -F "$file1") ||
5854                 error "cannot get fid for file $file1"
5855         for i in $(seq 2 $total_count); do
5856                 local fid2=$($LFS getstripe -F $dir/file$i)
5857
5858                 [ "$fid2" == "$fid" ] ||
5859                         error "migrated hard link has mismatched FID"
5860         done
5861
5862         # make sure hard links were properly detected, and migration was
5863         # performed only once for the entire link set; nonlinked files should
5864         # also be migrated
5865         local actual=$(grep -c 'done migrate' <<< "$migrate_out")
5866         local expected=$(($uniq_count + 1))
5867
5868         [ "$actual" -eq  "$expected" ] ||
5869                 error "hard links individually migrated ($actual != $expected)"
5870
5871         # make sure the correct number of hard links are present
5872         local hardlinks=$(stat -c '%h' "$file1")
5873
5874         [ $hardlinks -eq $total_count ] ||
5875                 error "num hard links $hardlinks != $total_count"
5876         echo "done"
5877
5878         return 0
5879 }
5880
5881 test_56xb() {
5882         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
5883                 skip "Need MDS version at least 2.10.55"
5884
5885         local dir="$DIR/$tdir"
5886
5887         test_mkdir "$dir" || error "cannot create dir $dir"
5888
5889         echo "testing lfs migrate mode when all links fit within xattrs"
5890         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
5891
5892         echo "testing rsync mode when all links fit within xattrs"
5893         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
5894
5895         echo "testing lfs migrate mode when all links do not fit within xattrs"
5896         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
5897
5898         echo "testing rsync mode when all links do not fit within xattrs"
5899         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
5900
5901
5902         # clean up
5903         rm -rf $dir
5904 }
5905 run_test 56xb "lfs migration hard link support"
5906
5907 test_56xc() {
5908         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5909
5910         local dir="$DIR/$tdir"
5911
5912         test_mkdir "$dir" || error "cannot create dir $dir"
5913
5914         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
5915         echo -n "Setting initial stripe for 20MB test file..."
5916         $LFS setstripe -c 2 -i 0 "$dir/20mb" || error "cannot setstripe"
5917         echo "done"
5918         echo -n "Sizing 20MB test file..."
5919         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
5920         echo "done"
5921         echo -n "Verifying small file autostripe count is 1..."
5922         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" &> /dev/null ||
5923                 error "cannot migrate 20MB file"
5924         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
5925                 error "cannot get stripe for $dir/20mb"
5926         [ $stripe_count -eq 1 ] ||
5927                 error "unexpected stripe count $stripe_count for 20MB file"
5928         rm -f "$dir/20mb"
5929         echo "done"
5930
5931         # Test 2: File is small enough to fit within the available space on
5932         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
5933         # have at least an additional 1KB for each desired stripe for test 3
5934         echo -n "Setting stripe for 1GB test file..."
5935         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe"
5936         echo "done"
5937         echo -n "Sizing 1GB test file..."
5938         # File size is 1GB + 3KB
5939         truncate "$dir/1gb" 1073744896 &> /dev/null ||
5940                 error "cannot create 1GB test file"
5941         echo "done"
5942         echo -n "Migrating 1GB file..."
5943         $LFS_MIGRATE -y -A -C 1 "$dir/1gb" &> /dev/null ||
5944                 error "cannot migrate file"
5945         echo "done"
5946         echo -n "Verifying autostripe count is sqrt(n) + 1..."
5947         stripe_count=$($LFS getstripe -c "$dir/1gb") ||
5948                 error "cannot get stripe for $dir/1gb"
5949         [ $stripe_count -eq 2 ] ||
5950                 error "unexpected stripe count $stripe_count (expected 2)"
5951         echo "done"
5952
5953         # Test 3: File is too large to fit within the available space on
5954         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
5955         if [ $OSTCOUNT -ge 3 ]; then
5956                 # The required available space is calculated as
5957                 # file size (1GB + 3KB) / OST count (3).
5958                 local kb_per_ost=349526
5959
5960                 echo -n "Migrating 1GB file..."
5961                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" &>> \
5962                         /dev/null || error "cannot migrate file"
5963                 echo "done"
5964
5965                 stripe_count=$($LFS getstripe -c "$dir/1gb")
5966                 echo -n "Verifying autostripe count with limited space..."
5967                 [ "$stripe_count" -a $stripe_count -eq 3 ] ||
5968                         error "unexpected stripe count $stripe_count (wanted 3)"
5969                 echo "done"
5970         fi
5971
5972         # clean up
5973         rm -rf $dir
5974 }
5975 run_test 56xc "lfs migration autostripe"
5976
5977 test_56y() {
5978         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
5979                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
5980
5981         local res=""
5982         local dir=$DIR/$tdir
5983         local f1=$dir/file1
5984         local f2=$dir/file2
5985
5986         test_mkdir -p $dir || error "creating dir $dir"
5987         touch $f1 || error "creating std file $f1"
5988         $MULTIOP $f2 H2c || error "creating released file $f2"
5989
5990         # a directory can be raid0, so ask only for files
5991         res=$($LFS find $dir -L raid0 -type f | wc -l)
5992         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
5993
5994         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
5995         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
5996
5997         # only files can be released, so no need to force file search
5998         res=$($LFS find $dir -L released)
5999         [[ $res == $f2 ]] || error "search released: found $res != $f2"
6000
6001         res=$($LFS find $dir -type f \! -L released)
6002         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
6003 }
6004 run_test 56y "lfs find -L raid0|released"
6005
6006 test_56z() { # LU-4824
6007         # This checks to make sure 'lfs find' continues after errors
6008         # There are two classes of errors that should be caught:
6009         # - If multiple paths are provided, all should be searched even if one
6010         #   errors out
6011         # - If errors are encountered during the search, it should not terminate
6012         #   early
6013         local dir=$DIR/$tdir
6014         local i
6015
6016         test_mkdir $dir
6017         for i in d{0..9}; do
6018                 test_mkdir $dir/$i
6019         done
6020         touch $dir/d{0..9}/$tfile
6021         $LFS find $DIR/non_existent_dir $dir &&
6022                 error "$LFS find did not return an error"
6023         # Make a directory unsearchable. This should NOT be the last entry in
6024         # directory order.  Arbitrarily pick the 6th entry
6025         chmod 700 $($LFS find $dir -type d | sed '6!d')
6026
6027         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
6028
6029         # The user should be able to see 10 directories and 9 files
6030         [ $count == 19 ] || error "$LFS find did not continue after error"
6031 }
6032 run_test 56z "lfs find should continue after an error"
6033
6034 test_56aa() { # LU-5937
6035         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
6036
6037         local dir=$DIR/$tdir
6038
6039         mkdir $dir
6040         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
6041
6042         createmany -o $dir/striped_dir/${tfile}- 1024
6043         local dirs=$($LFS find --size +8k $dir/)
6044
6045         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
6046 }
6047 run_test 56aa "lfs find --size under striped dir"
6048
6049 test_56ab() { # LU-10705
6050         test_mkdir $DIR/$tdir
6051         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
6052         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
6053         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
6054         # Flush writes to ensure valid blocks.  Need to be more thorough for
6055         # ZFS, since blocks are not allocated/returned to client immediately.
6056         sync_all_data
6057         wait_zfs_commit ost1 2
6058         cancel_lru_locks osc
6059         ls -ls $DIR/$tdir
6060
6061         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
6062
6063         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
6064
6065         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
6066         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
6067
6068         rm -f $DIR/$tdir/$tfile.[123]
6069 }
6070 run_test 56ab "lfs find --blocks"
6071
6072 test_56ba() {
6073         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
6074                 skip "Need MDS version at least 2.10.50"
6075
6076         # Create composite files with one component
6077         local dir=$DIR/$tdir
6078
6079         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
6080         # Create composite files with three components
6081         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
6082         # Create non-composite files
6083         createmany -o $dir/${tfile}- 10
6084
6085         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
6086
6087         [[ $nfiles == 10 ]] ||
6088                 error "lfs find -E 1M found $nfiles != 10 files"
6089
6090         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
6091         [[ $nfiles == 25 ]] ||
6092                 error "lfs find ! -E 1M found $nfiles != 25 files"
6093
6094         # All files have a component that starts at 0
6095         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
6096         [[ $nfiles == 35 ]] ||
6097                 error "lfs find --component-start 0 - $nfiles != 35 files"
6098
6099         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
6100         [[ $nfiles == 15 ]] ||
6101                 error "lfs find --component-start 2M - $nfiles != 15 files"
6102
6103         # All files created here have a componenet that does not starts at 2M
6104         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
6105         [[ $nfiles == 35 ]] ||
6106                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
6107
6108         # Find files with a specified number of components
6109         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
6110         [[ $nfiles == 15 ]] ||
6111                 error "lfs find --component-count 3 - $nfiles != 15 files"
6112
6113         # Remember non-composite files have a component count of zero
6114         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
6115         [[ $nfiles == 10 ]] ||
6116                 error "lfs find --component-count 0 - $nfiles != 10 files"
6117
6118         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
6119         [[ $nfiles == 20 ]] ||
6120                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
6121
6122         # All files have a flag called "init"
6123         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
6124         [[ $nfiles == 35 ]] ||
6125                 error "lfs find --component-flags init - $nfiles != 35 files"
6126
6127         # Multi-component files will have a component not initialized
6128         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
6129         [[ $nfiles == 15 ]] ||
6130                 error "lfs find !--component-flags init - $nfiles != 15 files"
6131
6132         rm -rf $dir
6133
6134 }
6135 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
6136
6137 test_56ca() {
6138         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
6139                 skip "Need MDS version at least 2.10.57"
6140
6141         local td=$DIR/$tdir
6142         local tf=$td/$tfile
6143         local dir
6144         local nfiles
6145         local cmd
6146         local i
6147         local j
6148
6149         # create mirrored directories and mirrored files
6150         mkdir $td || error "mkdir $td failed"
6151         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
6152         createmany -o $tf- 10 || error "create $tf- failed"
6153
6154         for i in $(seq 2); do
6155                 dir=$td/dir$i
6156                 mkdir $dir || error "mkdir $dir failed"
6157                 $LFS mirror create -N$((3 + i)) $dir ||
6158                         error "create mirrored dir $dir failed"
6159                 createmany -o $dir/$tfile- 10 ||
6160                         error "create $dir/$tfile- failed"
6161         done
6162
6163         # change the states of some mirrored files
6164         echo foo > $tf-6
6165         for i in $(seq 2); do
6166                 dir=$td/dir$i
6167                 for j in $(seq 4 9); do
6168                         echo foo > $dir/$tfile-$j
6169                 done
6170         done
6171
6172         # find mirrored files with specific mirror count
6173         cmd="$LFS find --mirror-count 3 --type f $td"
6174         nfiles=$($cmd | wc -l)
6175         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
6176
6177         cmd="$LFS find ! --mirror-count 3 --type f $td"
6178         nfiles=$($cmd | wc -l)
6179         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
6180
6181         cmd="$LFS find --mirror-count +2 --type f $td"
6182         nfiles=$($cmd | wc -l)
6183         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6184
6185         cmd="$LFS find --mirror-count -6 --type f $td"
6186         nfiles=$($cmd | wc -l)
6187         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6188
6189         # find mirrored files with specific file state
6190         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
6191         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
6192
6193         cmd="$LFS find --mirror-state=ro --type f $td"
6194         nfiles=$($cmd | wc -l)
6195         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
6196
6197         cmd="$LFS find ! --mirror-state=ro --type f $td"
6198         nfiles=$($cmd | wc -l)
6199         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6200
6201         cmd="$LFS find --mirror-state=wp --type f $td"
6202         nfiles=$($cmd | wc -l)
6203         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6204
6205         cmd="$LFS find ! --mirror-state=sp --type f $td"
6206         nfiles=$($cmd | wc -l)
6207         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6208 }
6209 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
6210
6211 test_57a() {
6212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6213         # note test will not do anything if MDS is not local
6214         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6215                 skip_env "ldiskfs only test"
6216         fi
6217         remote_mds_nodsh && skip "remote MDS with nodsh"
6218
6219         local MNTDEV="osd*.*MDT*.mntdev"
6220         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
6221         [ -z "$DEV" ] && error "can't access $MNTDEV"
6222         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
6223                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
6224                         error "can't access $DEV"
6225                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
6226                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
6227                 rm $TMP/t57a.dump
6228         done
6229 }
6230 run_test 57a "verify MDS filesystem created with large inodes =="
6231
6232 test_57b() {
6233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6234         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6235                 skip_env "ldiskfs only test"
6236         fi
6237         remote_mds_nodsh && skip "remote MDS with nodsh"
6238
6239         local dir=$DIR/$tdir
6240         local filecount=100
6241         local file1=$dir/f1
6242         local fileN=$dir/f$filecount
6243
6244         rm -rf $dir || error "removing $dir"
6245         test_mkdir -c1 $dir
6246         local mdtidx=$($LFS getstripe -m $dir)
6247         local mdtname=MDT$(printf %04x $mdtidx)
6248         local facet=mds$((mdtidx + 1))
6249
6250         echo "mcreating $filecount files"
6251         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
6252
6253         # verify that files do not have EAs yet
6254         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
6255                 error "$file1 has an EA"
6256         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
6257                 error "$fileN has an EA"
6258
6259         sync
6260         sleep 1
6261         df $dir  #make sure we get new statfs data
6262         local mdsfree=$(do_facet $facet \
6263                         lctl get_param -n osd*.*$mdtname.kbytesfree)
6264         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6265         local file
6266
6267         echo "opening files to create objects/EAs"
6268         for file in $(seq -f $dir/f%g 1 $filecount); do
6269                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
6270                         error "opening $file"
6271         done
6272
6273         # verify that files have EAs now
6274         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
6275         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
6276
6277         sleep 1  #make sure we get new statfs data
6278         df $dir
6279         local mdsfree2=$(do_facet $facet \
6280                          lctl get_param -n osd*.*$mdtname.kbytesfree)
6281         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6282
6283         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
6284                 if [ "$mdsfree" != "$mdsfree2" ]; then
6285                         error "MDC before $mdcfree != after $mdcfree2"
6286                 else
6287                         echo "MDC before $mdcfree != after $mdcfree2"
6288                         echo "unable to confirm if MDS has large inodes"
6289                 fi
6290         fi
6291         rm -rf $dir
6292 }
6293 run_test 57b "default LOV EAs are stored inside large inodes ==="
6294
6295 test_58() {
6296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6297         [ -z "$(which wiretest 2>/dev/null)" ] &&
6298                         skip_env "could not find wiretest"
6299
6300         wiretest
6301 }
6302 run_test 58 "verify cross-platform wire constants =============="
6303
6304 test_59() {
6305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6306
6307         echo "touch 130 files"
6308         createmany -o $DIR/f59- 130
6309         echo "rm 130 files"
6310         unlinkmany $DIR/f59- 130
6311         sync
6312         # wait for commitment of removal
6313         wait_delete_completed
6314 }
6315 run_test 59 "verify cancellation of llog records async ========="
6316
6317 TEST60_HEAD="test_60 run $RANDOM"
6318 test_60a() {
6319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6320         remote_mgs_nodsh && skip "remote MGS with nodsh"
6321         do_facet mgs "! which run-llog.sh &> /dev/null" &&
6322                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
6323                         skip_env "missing subtest run-llog.sh"
6324
6325         log "$TEST60_HEAD - from kernel mode"
6326         do_facet mgs "$LCTL dk > /dev/null"
6327         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
6328         do_facet mgs $LCTL dk > $TMP/$tfile
6329
6330         # LU-6388: test llog_reader
6331         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
6332         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
6333         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
6334                         skip_env "missing llog_reader"
6335         local fstype=$(facet_fstype mgs)
6336         [ $fstype != ldiskfs -a $fstype != zfs ] &&
6337                 skip_env "Only for ldiskfs or zfs type mgs"
6338
6339         local mntpt=$(facet_mntpt mgs)
6340         local mgsdev=$(mgsdevname 1)
6341         local fid_list
6342         local fid
6343         local rec_list
6344         local rec
6345         local rec_type
6346         local obj_file
6347         local path
6348         local seq
6349         local oid
6350         local pass=true
6351
6352         #get fid and record list
6353         fid_list=($(awk '/9_sub.*record/ { print $NF }' /$TMP/$tfile |
6354                 tail -n 4))
6355         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' /$TMP/$tfile |
6356                 tail -n 4))
6357         #remount mgs as ldiskfs or zfs type
6358         stop mgs || error "stop mgs failed"
6359         mount_fstype mgs || error "remount mgs failed"
6360         for ((i = 0; i < ${#fid_list[@]}; i++)); do
6361                 fid=${fid_list[i]}
6362                 rec=${rec_list[i]}
6363                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
6364                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
6365                 oid=$((16#$oid))
6366
6367                 case $fstype in
6368                         ldiskfs )
6369                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
6370                         zfs )
6371                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
6372                 esac
6373                 echo "obj_file is $obj_file"
6374                 do_facet mgs $llog_reader $obj_file
6375
6376                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
6377                         awk '{ print $3 }' | sed -e "s/^type=//g")
6378                 if [ $rec_type != $rec ]; then
6379                         echo "FAILED test_60a wrong record type $rec_type," \
6380                               "should be $rec"
6381                         pass=false
6382                         break
6383                 fi
6384
6385                 #check obj path if record type is LLOG_LOGID_MAGIC
6386                 if [ "$rec" == "1064553b" ]; then
6387                         path=$(do_facet mgs $llog_reader $obj_file |
6388                                 grep "path=" | awk '{ print $NF }' |
6389                                 sed -e "s/^path=//g")
6390                         if [ $obj_file != $mntpt/$path ]; then
6391                                 echo "FAILED test_60a wrong obj path" \
6392                                       "$montpt/$path, should be $obj_file"
6393                                 pass=false
6394                                 break
6395                         fi
6396                 fi
6397         done
6398         rm -f $TMP/$tfile
6399         #restart mgs before "error", otherwise it will block the next test
6400         stop mgs || error "stop mgs failed"
6401         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
6402         $pass || error "test failed, see FAILED test_60a messages for specifics"
6403 }
6404 run_test 60a "llog_test run from kernel module and test llog_reader"
6405
6406 test_60b() { # bug 6411
6407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6408
6409         dmesg > $DIR/$tfile
6410         LLOG_COUNT=$(do_facet mgs dmesg |
6411                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
6412                           /llog_[a-z]*.c:[0-9]/ {
6413                                 if (marker)
6414                                         from_marker++
6415                                 from_begin++
6416                           }
6417                           END {
6418                                 if (marker)
6419                                         print from_marker
6420                                 else
6421                                         print from_begin
6422                           }")
6423
6424         [[ $LLOG_COUNT -gt 120 ]] &&
6425                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
6426 }
6427 run_test 60b "limit repeated messages from CERROR/CWARN"
6428
6429 test_60c() {
6430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6431
6432         echo "create 5000 files"
6433         createmany -o $DIR/f60c- 5000
6434 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
6435         lctl set_param fail_loc=0x80000137
6436         unlinkmany $DIR/f60c- 5000
6437         lctl set_param fail_loc=0
6438 }
6439 run_test 60c "unlink file when mds full"
6440
6441 test_60d() {
6442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6443
6444         SAVEPRINTK=$(lctl get_param -n printk)
6445         # verify "lctl mark" is even working"
6446         MESSAGE="test message ID $RANDOM $$"
6447         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6448         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
6449
6450         lctl set_param printk=0 || error "set lnet.printk failed"
6451         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
6452         MESSAGE="new test message ID $RANDOM $$"
6453         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
6454         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6455         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
6456
6457         lctl set_param -n printk="$SAVEPRINTK"
6458 }
6459 run_test 60d "test printk console message masking"
6460
6461 test_60e() {
6462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6463         remote_mds_nodsh && skip "remote MDS with nodsh"
6464
6465         touch $DIR/$tfile
6466 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
6467         do_facet mds1 lctl set_param fail_loc=0x15b
6468         rm $DIR/$tfile
6469 }
6470 run_test 60e "no space while new llog is being created"
6471
6472 test_60g() {
6473         local pid
6474
6475         test_mkdir -c $MDSCOUNT $DIR/$tdir
6476         $LFS setdirstripe -D -i -1 -c $MDSCOUNT $DIR/$tdir
6477
6478         (
6479                 local index=0
6480                 while true; do
6481                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
6482                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
6483                         index=$((index + 1))
6484                 done
6485         ) &
6486
6487         pid=$!
6488
6489         for i in $(seq 100); do 
6490                 # define OBD_FAIL_OSD_TXN_START    0x19a
6491                 do_facet mds1 lctl set_param fail_loc=0x8000019a
6492                 usleep 100
6493         done
6494
6495         kill -9 $pid
6496
6497         mkdir $DIR/$tdir/new || error "mkdir failed"
6498         rmdir $DIR/$tdir/new || error "rmdir failed"
6499 }
6500 run_test 60g "transaction abort won't cause MDT hung"
6501
6502 test_61a() {
6503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6504
6505         f="$DIR/f61"
6506         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
6507         cancel_lru_locks osc
6508         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
6509         sync
6510 }
6511 run_test 61a "mmap() writes don't make sync hang ================"
6512
6513 test_61b() {
6514         mmap_mknod_test $tfile || error "mmap_mknod_test failed"
6515 }
6516 run_test 61b "mmap() of unstriped file is successful"
6517
6518 # bug 2330 - insufficient obd_match error checking causes LBUG
6519 test_62() {
6520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6521
6522         f="$DIR/f62"
6523         echo foo > $f
6524         cancel_lru_locks osc
6525         lctl set_param fail_loc=0x405
6526         cat $f && error "cat succeeded, expect -EIO"
6527         lctl set_param fail_loc=0
6528 }
6529 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
6530 # match every page all of the time.
6531 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
6532
6533 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
6534 # Though this test is irrelevant anymore, it helped to reveal some
6535 # other grant bugs (LU-4482), let's keep it.
6536 test_63a() {   # was test_63
6537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6538
6539         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
6540
6541         for i in `seq 10` ; do
6542                 dd if=/dev/zero of=$DIR/f63 bs=8k &
6543                 sleep 5
6544                 kill $!
6545                 sleep 1
6546         done
6547
6548         rm -f $DIR/f63 || true
6549 }
6550 run_test 63a "Verify oig_wait interruption does not crash ======="
6551
6552 # bug 2248 - async write errors didn't return to application on sync
6553 # bug 3677 - async write errors left page locked
6554 test_63b() {
6555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6556
6557         debugsave
6558         lctl set_param debug=-1
6559
6560         # ensure we have a grant to do async writes
6561         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
6562         rm $DIR/$tfile
6563
6564         sync    # sync lest earlier test intercept the fail_loc
6565
6566         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
6567         lctl set_param fail_loc=0x80000406
6568         $MULTIOP $DIR/$tfile Owy && \
6569                 error "sync didn't return ENOMEM"
6570         sync; sleep 2; sync     # do a real sync this time to flush page
6571         lctl get_param -n llite.*.dump_page_cache | grep locked && \
6572                 error "locked page left in cache after async error" || true
6573         debugrestore
6574 }
6575 run_test 63b "async write errors should be returned to fsync ==="
6576
6577 test_64a () {
6578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6579
6580         df $DIR
6581         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
6582 }
6583 run_test 64a "verify filter grant calculations (in kernel) ====="
6584
6585 test_64b () {
6586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6587
6588         sh oos.sh $MOUNT || error "oos.sh failed: $?"
6589 }
6590 run_test 64b "check out-of-space detection on client"
6591
6592 test_64c() {
6593         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
6594 }
6595 run_test 64c "verify grant shrink"
6596
6597 # this does exactly what osc_request.c:osc_announce_cached() does in
6598 # order to calculate max amount of grants to ask from server
6599 want_grant() {
6600         local tgt=$1
6601
6602         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
6603         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
6604
6605         ((rpc_in_flight ++));
6606         nrpages=$((nrpages * rpc_in_flight))
6607
6608         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
6609
6610         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
6611
6612         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
6613         local undirty=$((nrpages * PAGE_SIZE))
6614
6615         local max_extent_pages
6616         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
6617             grep grant_max_extent_size | awk '{print $2}')
6618         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
6619         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
6620         local grant_extent_tax
6621         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
6622             grep grant_extent_tax | awk '{print $2}')
6623
6624         undirty=$((undirty + nrextents * grant_extent_tax))
6625
6626         echo $undirty
6627 }
6628
6629 # this is size of unit for grant allocation. It should be equal to
6630 # what tgt_grant.c:tgt_grant_chunk() calculates
6631 grant_chunk() {
6632         local tgt=$1
6633         local max_brw_size
6634         local grant_extent_tax
6635
6636         max_brw_size=$($LCTL get_param osc.${tgt}.import |
6637             grep max_brw_size | awk '{print $2}')
6638
6639         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
6640             grep grant_extent_tax | awk '{print $2}')
6641
6642         echo $(((max_brw_size + grant_extent_tax) * 2))
6643 }
6644
6645 test_64d() {
6646         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
6647                 skip "OST < 2.10.55 doesn't limit grants enough"
6648
6649         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
6650         local file=$DIR/$tfile
6651
6652         [[ $($LCTL get_param osc.${tgt}.import |
6653              grep "connect_flags:.*grant_param") ]] ||
6654                 skip "no grant_param connect flag"
6655
6656         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
6657
6658         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
6659
6660         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
6661         stack_trap "rm -f $file" EXIT
6662
6663         $LFS setstripe $file -i 0 -c 1
6664         dd if=/dev/zero of=$file bs=1M count=1000 &
6665         ddpid=$!
6666
6667         while true
6668         do
6669                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
6670                 if [[ $cur_grant -gt $max_cur_granted ]]
6671                 then
6672                         kill $ddpid
6673                         error "cur_grant $cur_grant > $max_cur_granted"
6674                 fi
6675                 kill -0 $ddpid
6676                 [[ $? -ne 0 ]] && break;
6677                 sleep 2
6678         done
6679
6680         rm -f $DIR/$tfile
6681         wait_delete_completed
6682         $LCTL set_param debug="$olddebug" 2> /dev/null || true
6683 }
6684 run_test 64d "check grant limit exceed"
6685
6686 # bug 1414 - set/get directories' stripe info
6687 test_65a() {
6688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6689
6690         test_mkdir $DIR/$tdir
6691         touch $DIR/$tdir/f1
6692         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
6693 }
6694 run_test 65a "directory with no stripe info"
6695
6696 test_65b() {
6697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6698
6699         test_mkdir $DIR/$tdir
6700         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6701
6702         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6703                                                 error "setstripe"
6704         touch $DIR/$tdir/f2
6705         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
6706 }
6707 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
6708
6709 test_65c() {
6710         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6711         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
6712
6713         test_mkdir $DIR/$tdir
6714         local stripesize=$($LFS getstripe -S $DIR/$tdir)
6715
6716         $LFS setstripe -S $((stripesize * 4)) -i 1 \
6717                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
6718         touch $DIR/$tdir/f3
6719         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
6720 }
6721 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
6722
6723 test_65d() {
6724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6725
6726         test_mkdir $DIR/$tdir
6727         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
6728         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6729
6730         if [[ $STRIPECOUNT -le 0 ]]; then
6731                 sc=1
6732         elif [[ $STRIPECOUNT -gt 2000 ]]; then
6733 #LOV_MAX_STRIPE_COUNT is 2000
6734                 [[ $OSTCOUNT -gt 2000 ]] && sc=2000 || sc=$(($OSTCOUNT - 1))
6735         else
6736                 sc=$(($STRIPECOUNT - 1))
6737         fi
6738         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
6739         touch $DIR/$tdir/f4 $DIR/$tdir/f5
6740         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
6741                 error "lverify failed"
6742 }
6743 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
6744
6745 test_65e() {
6746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6747
6748         test_mkdir $DIR/$tdir
6749
6750         $LFS setstripe $DIR/$tdir || error "setstripe"
6751         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
6752                                         error "no stripe info failed"
6753         touch $DIR/$tdir/f6
6754         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
6755 }
6756 run_test 65e "directory setstripe defaults"
6757
6758 test_65f() {
6759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6760
6761         test_mkdir $DIR/${tdir}f
6762         $RUNAS $LFS setstripe $DIR/${tdir}f &&
6763                 error "setstripe succeeded" || true
6764 }
6765 run_test 65f "dir setstripe permission (should return error) ==="
6766
6767 test_65g() {
6768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6769
6770         test_mkdir $DIR/$tdir
6771         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6772
6773         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6774                 error "setstripe -S failed"
6775         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
6776         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
6777                 error "delete default stripe failed"
6778 }
6779 run_test 65g "directory setstripe -d"
6780
6781 test_65h() {
6782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6783
6784         test_mkdir $DIR/$tdir
6785         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6786
6787         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6788                 error "setstripe -S failed"
6789         test_mkdir $DIR/$tdir/dd1
6790         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
6791                 error "stripe info inherit failed"
6792 }
6793 run_test 65h "directory stripe info inherit ===================="
6794
6795 test_65i() {
6796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6797
6798         save_layout_restore_at_exit $MOUNT
6799
6800         # bug6367: set non-default striping on root directory
6801         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
6802
6803         # bug12836: getstripe on -1 default directory striping
6804         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
6805
6806         # bug12836: getstripe -v on -1 default directory striping
6807         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
6808
6809         # bug12836: new find on -1 default directory striping
6810         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
6811 }
6812 run_test 65i "various tests to set root directory striping"
6813
6814 test_65j() { # bug6367
6815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6816
6817         sync; sleep 1
6818
6819         # if we aren't already remounting for each test, do so for this test
6820         if [ "$CLEANUP" = ":" -a "$I_MOUNTED" = "yes" ]; then
6821                 cleanup || error "failed to unmount"
6822                 setup
6823         fi
6824
6825         save_layout_restore_at_exit $MOUNT
6826
6827         $LFS setstripe -d $MOUNT || error "setstripe failed"
6828 }
6829 run_test 65j "set default striping on root directory (bug 6367)="
6830
6831 cleanup_65k() {
6832         rm -rf $DIR/$tdir
6833         wait_delete_completed
6834         do_facet $SINGLEMDS "lctl set_param -n \
6835                 osp.$ost*MDT0000.max_create_count=$max_count"
6836         do_facet $SINGLEMDS "lctl set_param -n \
6837                 osp.$ost*MDT0000.create_count=$count"
6838         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
6839         echo $INACTIVE_OSC "is Activate"
6840
6841         wait_osc_import_state mds ost$ostnum FULL
6842 }
6843
6844 test_65k() { # bug11679
6845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6846         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6847         remote_mds_nodsh && skip "remote MDS with nodsh"
6848
6849         local disable_precreate=true
6850         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
6851                 disable_precreate=false
6852
6853         echo "Check OST status: "
6854         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
6855                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
6856
6857         for OSC in $MDS_OSCS; do
6858                 echo $OSC "is active"
6859                 do_facet $SINGLEMDS lctl --device %$OSC activate
6860         done
6861
6862         for INACTIVE_OSC in $MDS_OSCS; do
6863                 local ost=$(osc_to_ost $INACTIVE_OSC)
6864                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
6865                                lov.*md*.target_obd |
6866                                awk -F: /$ost/'{ print $1 }' | head -n 1)
6867
6868                 mkdir -p $DIR/$tdir
6869                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
6870                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
6871
6872                 echo "Deactivate: " $INACTIVE_OSC
6873                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
6874
6875                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
6876                               osp.$ost*MDT0000.create_count")
6877                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
6878                                   osp.$ost*MDT0000.max_create_count")
6879                 $disable_precreate &&
6880                         do_facet $SINGLEMDS "lctl set_param -n \
6881                                 osp.$ost*MDT0000.max_create_count=0"
6882
6883                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
6884                         [ -f $DIR/$tdir/$idx ] && continue
6885                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
6886                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
6887                                 { cleanup_65k;
6888                                   error "setstripe $idx should succeed"; }
6889                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
6890                 done
6891                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
6892                 rmdir $DIR/$tdir
6893
6894                 do_facet $SINGLEMDS "lctl set_param -n \
6895                         osp.$ost*MDT0000.max_create_count=$max_count"
6896                 do_facet $SINGLEMDS "lctl set_param -n \
6897                         osp.$ost*MDT0000.create_count=$count"
6898                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
6899                 echo $INACTIVE_OSC "is Activate"
6900
6901                 wait_osc_import_state mds ost$ostnum FULL
6902         done
6903 }
6904 run_test 65k "validate manual striping works properly with deactivated OSCs"
6905
6906 test_65l() { # bug 12836
6907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6908
6909         test_mkdir -p $DIR/$tdir/test_dir
6910         $LFS setstripe -c -1 $DIR/$tdir/test_dir
6911         $LFS find -mtime -1 $DIR/$tdir >/dev/null
6912 }
6913 run_test 65l "lfs find on -1 stripe dir ========================"
6914
6915 test_65m() {
6916         local layout=$(save_layout $MOUNT)
6917         $RUNAS $LFS setstripe -c 2 $MOUNT && {
6918                 restore_layout $MOUNT $layout
6919                 error "setstripe should fail by non-root users"
6920         }
6921         true
6922 }
6923 run_test 65m "normal user can't set filesystem default stripe"
6924
6925 test_65n() {
6926         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
6927         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.12.50) ]] ||
6928                 skip "Need MDS version at least 2.12.50"
6929         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
6930
6931         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
6932         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
6933         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
6934
6935         local root_layout=$(save_layout $MOUNT)
6936         stack_trap "restore_layout $MOUNT $root_layout" EXIT
6937
6938         # new subdirectory under root directory should not inherit
6939         # the default layout from root
6940         local dir1=$MOUNT/$tdir-1
6941         mkdir $dir1 || error "mkdir $dir1 failed"
6942         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
6943                 error "$dir1 shouldn't have LOV EA"
6944
6945         # delete the default layout on root directory
6946         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
6947
6948         local dir2=$MOUNT/$tdir-2
6949         mkdir $dir2 || error "mkdir $dir2 failed"
6950         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
6951                 error "$dir2 shouldn't have LOV EA"
6952
6953         # set a new striping pattern on root directory
6954         local def_stripe_size=$($LFS getstripe -S $MOUNT)
6955         local new_def_stripe_size=$((def_stripe_size * 2))
6956         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
6957                 error "set stripe size on $MOUNT failed"
6958
6959         # new file created in $dir2 should inherit the new stripe size from
6960         # the filesystem default
6961         local file2=$dir2/$tfile-2
6962         touch $file2 || error "touch $file2 failed"
6963
6964         local file2_stripe_size=$($LFS getstripe -S $file2)
6965         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
6966                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
6967
6968         local dir3=$MOUNT/$tdir-3
6969         mkdir $dir3 || error "mkdir $dir3 failed"
6970         ! getfattr -n trusted.lov $dir3 &> /dev/null ||
6971                 error "$dir3 shouldn't have LOV EA"
6972
6973         # set OST pool on root directory
6974         local pool=$TESTNAME
6975         pool_add $pool || error "add $pool failed"
6976         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
6977                 error "add targets to $pool failed"
6978
6979         $LFS setstripe -p $pool $MOUNT ||
6980                 error "set OST pool on $MOUNT failed"
6981
6982         # new file created in $dir3 should inherit the pool from
6983         # the filesystem default
6984         local file3=$dir3/$tfile-3
6985         touch $file3 || error "touch $file3 failed"
6986
6987         local file3_pool=$($LFS getstripe -p $file3)
6988         [[ "$file3_pool" = "$pool" ]] ||
6989                 error "$file3 didn't inherit OST pool $pool"
6990
6991         local dir4=$MOUNT/$tdir-4
6992         mkdir $dir4 || error "mkdir $dir4 failed"
6993         ! getfattr -n trusted.lov $dir4 &> /dev/null ||
6994                 error "$dir4 shouldn't have LOV EA"
6995
6996         # new file created in $dir4 should inherit the pool from
6997         # the filesystem default
6998         local file4=$dir4/$tfile-4
6999         touch $file4 || error "touch $file4 failed"
7000
7001         local file4_pool=$($LFS getstripe -p $file4)
7002         [[ "$file4_pool" = "$pool" ]] ||
7003                 error "$file4 didn't inherit OST pool $pool"
7004
7005         # new subdirectory under non-root directory should inherit
7006         # the default layout from its parent directory
7007         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
7008                 error "set directory layout on $dir4 failed"
7009
7010         local dir5=$dir4/$tdir-5
7011         mkdir $dir5 || error "mkdir $dir5 failed"
7012
7013         local dir4_layout=$(get_layout_param $dir4)
7014         local dir5_layout=$(get_layout_param $dir5)
7015         [[ "$dir4_layout" = "$dir5_layout" ]] ||
7016                 error "$dir5 should inherit the default layout from $dir4"
7017 }
7018 run_test 65n "don't inherit default layout from root for new subdirectories"
7019
7020 # bug 2543 - update blocks count on client
7021 test_66() {
7022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7023
7024         COUNT=${COUNT:-8}
7025         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
7026         sync; sync_all_data; sync; sync_all_data
7027         cancel_lru_locks osc
7028         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
7029         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
7030 }
7031 run_test 66 "update inode blocks count on client ==============="
7032
7033 meminfo() {
7034         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
7035 }
7036
7037 swap_used() {
7038         swapon -s | awk '($1 == "'$1'") { print $4 }'
7039 }
7040
7041 # bug5265, obdfilter oa2dentry return -ENOENT
7042 # #define OBD_FAIL_SRV_ENOENT 0x217
7043 test_69() {
7044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7045         remote_ost_nodsh && skip "remote OST with nodsh"
7046
7047         f="$DIR/$tfile"
7048         $LFS setstripe -c 1 -i 0 $f
7049
7050         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
7051
7052         do_facet ost1 lctl set_param fail_loc=0x217
7053         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
7054         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
7055
7056         do_facet ost1 lctl set_param fail_loc=0
7057         $DIRECTIO write $f 0 2 || error "write error"
7058
7059         cancel_lru_locks osc
7060         $DIRECTIO read $f 0 1 || error "read error"
7061
7062         do_facet ost1 lctl set_param fail_loc=0x217
7063         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
7064
7065         do_facet ost1 lctl set_param fail_loc=0
7066         rm -f $f
7067 }
7068 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
7069
7070 test_71() {
7071         test_mkdir $DIR/$tdir
7072         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
7073         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
7074 }
7075 run_test 71 "Running dbench on lustre (don't segment fault) ===="
7076
7077 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
7078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7079         [ "$RUNAS_ID" = "$UID" ] &&
7080                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7081         # Check that testing environment is properly set up. Skip if not
7082         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
7083                 skip_env "User $RUNAS_ID does not exist - skipping"
7084
7085         touch $DIR/$tfile
7086         chmod 777 $DIR/$tfile
7087         chmod ug+s $DIR/$tfile
7088         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
7089                 error "$RUNAS dd $DIR/$tfile failed"
7090         # See if we are still setuid/sgid
7091         test -u $DIR/$tfile -o -g $DIR/$tfile &&
7092                 error "S/gid is not dropped on write"
7093         # Now test that MDS is updated too
7094         cancel_lru_locks mdc
7095         test -u $DIR/$tfile -o -g $DIR/$tfile &&
7096                 error "S/gid is not dropped on MDS"
7097         rm -f $DIR/$tfile
7098 }
7099 run_test 72a "Test that remove suid works properly (bug5695) ===="
7100
7101 test_72b() { # bug 24226 -- keep mode setting when size is not changing
7102         local perm
7103
7104         [ "$RUNAS_ID" = "$UID" ] &&
7105                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7106         [ "$RUNAS_ID" -eq 0 ] &&
7107                 skip_env "RUNAS_ID = 0 -- skipping"
7108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7109         # Check that testing environment is properly set up. Skip if not
7110         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
7111                 skip_env "User $RUNAS_ID does not exist - skipping"
7112
7113         touch $DIR/${tfile}-f{g,u}
7114         test_mkdir $DIR/${tfile}-dg
7115         test_mkdir $DIR/${tfile}-du
7116         chmod 770 $DIR/${tfile}-{f,d}{g,u}
7117         chmod g+s $DIR/${tfile}-{f,d}g
7118         chmod u+s $DIR/${tfile}-{f,d}u
7119         for perm in 777 2777 4777; do
7120                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
7121                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
7122                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
7123                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
7124         done
7125         true
7126 }
7127 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
7128
7129 # bug 3462 - multiple simultaneous MDC requests
7130 test_73() {
7131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7132
7133         test_mkdir $DIR/d73-1
7134         test_mkdir $DIR/d73-2
7135         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
7136         pid1=$!
7137
7138         lctl set_param fail_loc=0x80000129
7139         $MULTIOP $DIR/d73-1/f73-2 Oc &
7140         sleep 1
7141         lctl set_param fail_loc=0
7142
7143         $MULTIOP $DIR/d73-2/f73-3 Oc &
7144         pid3=$!
7145
7146         kill -USR1 $pid1
7147         wait $pid1 || return 1
7148
7149         sleep 25
7150
7151         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
7152         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
7153         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
7154
7155         rm -rf $DIR/d73-*
7156 }
7157 run_test 73 "multiple MDC requests (should not deadlock)"
7158
7159 test_74a() { # bug 6149, 6184
7160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7161
7162         touch $DIR/f74a
7163         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7164         #
7165         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7166         # will spin in a tight reconnection loop
7167         $LCTL set_param fail_loc=0x8000030e
7168         # get any lock that won't be difficult - lookup works.
7169         ls $DIR/f74a
7170         $LCTL set_param fail_loc=0
7171         rm -f $DIR/f74a
7172         true
7173 }
7174 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
7175
7176 test_74b() { # bug 13310
7177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7178
7179         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7180         #
7181         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7182         # will spin in a tight reconnection loop
7183         $LCTL set_param fail_loc=0x8000030e
7184         # get a "difficult" lock
7185         touch $DIR/f74b
7186         $LCTL set_param fail_loc=0
7187         rm -f $DIR/f74b
7188         true
7189 }
7190 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
7191
7192 test_74c() {
7193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7194
7195         #define OBD_FAIL_LDLM_NEW_LOCK
7196         $LCTL set_param fail_loc=0x319
7197         touch $DIR/$tfile && error "touch successful"
7198         $LCTL set_param fail_loc=0
7199         true
7200 }
7201 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
7202
7203 num_inodes() {
7204         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
7205 }
7206
7207 test_76() { # Now for bug 20433, added originally in bug 1443
7208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7209
7210         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
7211
7212         cancel_lru_locks osc
7213         BEFORE_INODES=$(num_inodes)
7214         echo "before inodes: $BEFORE_INODES"
7215         local COUNT=1000
7216         [ "$SLOW" = "no" ] && COUNT=100
7217         for i in $(seq $COUNT); do
7218                 touch $DIR/$tfile
7219                 rm -f $DIR/$tfile
7220         done
7221         cancel_lru_locks osc
7222         AFTER_INODES=$(num_inodes)
7223         echo "after inodes: $AFTER_INODES"
7224         local wait=0
7225         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
7226                 sleep 2
7227                 AFTER_INODES=$(num_inodes)
7228                 wait=$((wait+2))
7229                 echo "wait $wait seconds inodes: $AFTER_INODES"
7230                 if [ $wait -gt 30 ]; then
7231                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
7232                 fi
7233         done
7234 }
7235 run_test 76 "confirm clients recycle inodes properly ===="
7236
7237
7238 export ORIG_CSUM=""
7239 set_checksums()
7240 {
7241         # Note: in sptlrpc modes which enable its own bulk checksum, the
7242         # original crc32_le bulk checksum will be automatically disabled,
7243         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
7244         # will be checked by sptlrpc code against sptlrpc bulk checksum.
7245         # In this case set_checksums() will not be no-op, because sptlrpc
7246         # bulk checksum will be enabled all through the test.
7247
7248         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
7249         lctl set_param -n osc.*.checksums $1
7250         return 0
7251 }
7252
7253 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7254                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
7255 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7256                              tr -d [] | head -n1)}
7257 set_checksum_type()
7258 {
7259         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
7260         log "set checksum type to $1"
7261         return 0
7262 }
7263 F77_TMP=$TMP/f77-temp
7264 F77SZ=8
7265 setup_f77() {
7266         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
7267                 error "error writing to $F77_TMP"
7268 }
7269
7270 test_77a() { # bug 10889
7271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7272         $GSS && skip_env "could not run with gss"
7273
7274         [ ! -f $F77_TMP ] && setup_f77
7275         set_checksums 1
7276         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
7277         set_checksums 0
7278         rm -f $DIR/$tfile
7279 }
7280 run_test 77a "normal checksum read/write operation"
7281
7282 test_77b() { # bug 10889
7283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7284         $GSS && skip_env "could not run with gss"
7285
7286         [ ! -f $F77_TMP ] && setup_f77
7287         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7288         $LCTL set_param fail_loc=0x80000409
7289         set_checksums 1
7290
7291         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7292                 error "dd error: $?"
7293         $LCTL set_param fail_loc=0
7294
7295         for algo in $CKSUM_TYPES; do
7296                 cancel_lru_locks osc
7297                 set_checksum_type $algo
7298                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7299                 $LCTL set_param fail_loc=0x80000408
7300                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
7301                 $LCTL set_param fail_loc=0
7302         done
7303         set_checksums 0
7304         set_checksum_type $ORIG_CSUM_TYPE
7305         rm -f $DIR/$tfile
7306 }
7307 run_test 77b "checksum error on client write, read"
7308
7309 cleanup_77c() {
7310         trap 0
7311         set_checksums 0
7312         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
7313         $check_ost &&
7314                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
7315         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
7316         $check_ost && [ -n "$ost_file_prefix" ] &&
7317                 do_facet ost1 rm -f ${ost_file_prefix}\*
7318 }
7319
7320 test_77c() {
7321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7322         $GSS && skip_env "could not run with gss"
7323         remote_ost_nodsh && skip "remote OST with nodsh"
7324
7325         local bad1
7326         local osc_file_prefix
7327         local osc_file
7328         local check_ost=false
7329         local ost_file_prefix
7330         local ost_file
7331         local orig_cksum
7332         local dump_cksum
7333         local fid
7334
7335         # ensure corruption will occur on first OSS/OST
7336         $LFS setstripe -i 0 $DIR/$tfile
7337
7338         [ ! -f $F77_TMP ] && setup_f77
7339         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7340                 error "dd write error: $?"
7341         fid=$($LFS path2fid $DIR/$tfile)
7342
7343         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
7344         then
7345                 check_ost=true
7346                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
7347                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
7348         else
7349                 echo "OSS do not support bulk pages dump upon error"
7350         fi
7351
7352         osc_file_prefix=$($LCTL get_param -n debug_path)
7353         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
7354
7355         trap cleanup_77c EXIT
7356
7357         set_checksums 1
7358         # enable bulk pages dump upon error on Client
7359         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
7360         # enable bulk pages dump upon error on OSS
7361         $check_ost &&
7362                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
7363
7364         # flush Client cache to allow next read to reach OSS
7365         cancel_lru_locks osc
7366
7367         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
7368         $LCTL set_param fail_loc=0x80000408
7369         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
7370         $LCTL set_param fail_loc=0
7371
7372         rm -f $DIR/$tfile
7373
7374         # check cksum dump on Client
7375         osc_file=$(ls ${osc_file_prefix}*)
7376         [ -n "$osc_file" ] || error "no checksum dump file on Client"
7377         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
7378         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
7379         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
7380         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
7381                      cksum)
7382         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
7383         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7384                 error "dump content does not match on Client"
7385
7386         $check_ost || skip "No need to check cksum dump on OSS"
7387
7388         # check cksum dump on OSS
7389         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
7390         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
7391         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
7392         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
7393         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7394                 error "dump content does not match on OSS"
7395
7396         cleanup_77c
7397 }
7398 run_test 77c "checksum error on client read with debug"
7399
7400 test_77d() { # bug 10889
7401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7402         $GSS && skip_env "could not run with gss"
7403
7404         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7405         $LCTL set_param fail_loc=0x80000409
7406         set_checksums 1
7407         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7408                 error "direct write: rc=$?"
7409         $LCTL set_param fail_loc=0
7410         set_checksums 0
7411
7412         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7413         $LCTL set_param fail_loc=0x80000408
7414         set_checksums 1
7415         cancel_lru_locks osc
7416         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7417                 error "direct read: rc=$?"
7418         $LCTL set_param fail_loc=0
7419         set_checksums 0
7420 }
7421 run_test 77d "checksum error on OST direct write, read"
7422
7423 test_77f() { # bug 10889
7424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7425         $GSS && skip_env "could not run with gss"
7426
7427         set_checksums 1
7428         for algo in $CKSUM_TYPES; do
7429                 cancel_lru_locks osc
7430                 set_checksum_type $algo
7431                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7432                 $LCTL set_param fail_loc=0x409
7433                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
7434                         error "direct write succeeded"
7435                 $LCTL set_param fail_loc=0
7436         done
7437         set_checksum_type $ORIG_CSUM_TYPE
7438         set_checksums 0
7439 }
7440 run_test 77f "repeat checksum error on write (expect error)"
7441
7442 test_77g() { # bug 10889
7443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7444         $GSS && skip_env "could not run with gss"
7445         remote_ost_nodsh && skip "remote OST with nodsh"
7446
7447         [ ! -f $F77_TMP ] && setup_f77
7448
7449         local file=$DIR/$tfile
7450         stack_trap "rm -f $file" EXIT
7451
7452         $LFS setstripe -c 1 -i 0 $file
7453         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
7454         do_facet ost1 lctl set_param fail_loc=0x8000021a
7455         set_checksums 1
7456         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
7457                 error "write error: rc=$?"
7458         do_facet ost1 lctl set_param fail_loc=0
7459         set_checksums 0
7460
7461         cancel_lru_locks osc
7462         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
7463         do_facet ost1 lctl set_param fail_loc=0x8000021b
7464         set_checksums 1
7465         cmp $F77_TMP $file || error "file compare failed"
7466         do_facet ost1 lctl set_param fail_loc=0
7467         set_checksums 0
7468 }
7469 run_test 77g "checksum error on OST write, read"
7470
7471 test_77k() { # LU-10906
7472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7473         $GSS && skip_env "could not run with gss"
7474
7475         local cksum_param="osc.$FSNAME*.checksums"
7476         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
7477         local checksum
7478         local i
7479
7480         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
7481         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
7482         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
7483                 EXIT
7484
7485         for i in 0 1; do
7486                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
7487                         error "failed to set checksum=$i on MGS"
7488                 wait_update $HOSTNAME "$get_checksum" $i
7489                 #remount
7490                 echo "remount client, checksum should be $i"
7491                 remount_client $MOUNT || "failed to remount client"
7492                 checksum=$(eval $get_checksum)
7493                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7494         done
7495         # remove persistent param to avoid races with checksum mountopt below
7496         do_facet mgs $LCTL set_param -P -d $cksum_param ||
7497                 error "failed to delete checksum on MGS"
7498
7499         for opt in "checksum" "nochecksum"; do
7500                 #remount with mount option
7501                 echo "remount client with option $opt, checksum should be $i"
7502                 umount_client $MOUNT || "failed to umount client"
7503                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
7504                         "failed to mount client with option '$opt'"
7505                 checksum=$(eval $get_checksum)
7506                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7507                 i=$((i - 1))
7508         done
7509
7510         remount_client $MOUNT || "failed to remount client"
7511 }
7512 run_test 77k "enable/disable checksum correctly"
7513
7514 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
7515 rm -f $F77_TMP
7516 unset F77_TMP
7517
7518 cleanup_test_78() {
7519         trap 0
7520         rm -f $DIR/$tfile
7521 }
7522
7523 test_78() { # bug 10901
7524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7525         remote_ost || skip_env "local OST"
7526
7527         NSEQ=5
7528         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
7529         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
7530         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
7531         echo "MemTotal: $MEMTOTAL"
7532
7533         # reserve 256MB of memory for the kernel and other running processes,
7534         # and then take 1/2 of the remaining memory for the read/write buffers.
7535         if [ $MEMTOTAL -gt 512 ] ;then
7536                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
7537         else
7538                 # for those poor memory-starved high-end clusters...
7539                 MEMTOTAL=$((MEMTOTAL / 2))
7540         fi
7541         echo "Mem to use for directio: $MEMTOTAL"
7542
7543         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
7544         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
7545         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
7546         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
7547                 head -n1)
7548         echo "Smallest OST: $SMALLESTOST"
7549         [[ $SMALLESTOST -lt 10240 ]] &&
7550                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
7551
7552         trap cleanup_test_78 EXIT
7553
7554         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
7555                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
7556
7557         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
7558         echo "File size: $F78SIZE"
7559         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
7560         for i in $(seq 1 $NSEQ); do
7561                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
7562                 echo directIO rdwr round $i of $NSEQ
7563                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
7564         done
7565
7566         cleanup_test_78
7567 }
7568 run_test 78 "handle large O_DIRECT writes correctly ============"
7569
7570 test_79() { # bug 12743
7571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7572
7573         wait_delete_completed
7574
7575         BKTOTAL=$(calc_osc_kbytes kbytestotal)
7576         BKFREE=$(calc_osc_kbytes kbytesfree)
7577         BKAVAIL=$(calc_osc_kbytes kbytesavail)
7578
7579         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
7580         DFTOTAL=`echo $STRING | cut -d, -f1`
7581         DFUSED=`echo $STRING  | cut -d, -f2`
7582         DFAVAIL=`echo $STRING | cut -d, -f3`
7583         DFFREE=$(($DFTOTAL - $DFUSED))
7584
7585         ALLOWANCE=$((64 * $OSTCOUNT))
7586
7587         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
7588            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
7589                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
7590         fi
7591         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
7592            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
7593                 error "df free($DFFREE) mismatch OST free($BKFREE)"
7594         fi
7595         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
7596            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
7597                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
7598         fi
7599 }
7600 run_test 79 "df report consistency check ======================="
7601
7602 test_80() { # bug 10718
7603         remote_ost_nodsh && skip "remote OST with nodsh"
7604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7605
7606         # relax strong synchronous semantics for slow backends like ZFS
7607         local soc="obdfilter.*.sync_on_lock_cancel"
7608         local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
7609         local hosts=
7610         if [ "$soc_old" != "never" ] &&
7611                 [ "$ost1_FSTYPE" != "ldiskfs" ]; then
7612                         hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
7613                                 facet_active_host $host; done | sort -u)
7614                         do_nodes $hosts lctl set_param $soc=never
7615         fi
7616
7617         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
7618         sync; sleep 1; sync
7619         local BEFORE=`date +%s`
7620         cancel_lru_locks osc
7621         local AFTER=`date +%s`
7622         local DIFF=$((AFTER-BEFORE))
7623         if [ $DIFF -gt 1 ] ; then
7624                 error "elapsed for 1M@1T = $DIFF"
7625         fi
7626
7627         [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
7628
7629         rm -f $DIR/$tfile
7630 }
7631 run_test 80 "Page eviction is equally fast at high offsets too  ===="
7632
7633 test_81a() { # LU-456
7634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7635         remote_ost_nodsh && skip "remote OST with nodsh"
7636
7637         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
7638         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
7639         do_facet ost1 lctl set_param fail_loc=0x80000228
7640
7641         # write should trigger a retry and success
7642         $LFS setstripe -i 0 -c 1 $DIR/$tfile
7643         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
7644         RC=$?
7645         if [ $RC -ne 0 ] ; then
7646                 error "write should success, but failed for $RC"
7647         fi
7648 }
7649 run_test 81a "OST should retry write when get -ENOSPC ==============="
7650
7651 test_81b() { # LU-456
7652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7653         remote_ost_nodsh && skip "remote OST with nodsh"
7654
7655         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
7656         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
7657         do_facet ost1 lctl set_param fail_loc=0x228
7658
7659         # write should retry several times and return -ENOSPC finally
7660         $LFS setstripe -i 0 -c 1 $DIR/$tfile
7661         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
7662         RC=$?
7663         ENOSPC=28
7664         if [ $RC -ne $ENOSPC ] ; then
7665                 error "dd should fail for -ENOSPC, but succeed."
7666         fi
7667 }
7668 run_test 81b "OST should return -ENOSPC when retry still fails ======="
7669
7670 test_82() { # LU-1031
7671         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
7672         local gid1=14091995
7673         local gid2=16022000
7674
7675         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
7676         local MULTIPID1=$!
7677         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
7678         local MULTIPID2=$!
7679         kill -USR1 $MULTIPID2
7680         sleep 2
7681         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
7682                 error "First grouplock does not block second one"
7683         else
7684                 echo "Second grouplock blocks first one"
7685         fi
7686         kill -USR1 $MULTIPID1
7687         wait $MULTIPID1
7688         wait $MULTIPID2
7689 }
7690 run_test 82 "Basic grouplock test"
7691
7692 test_99() {
7693         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
7694
7695         test_mkdir $DIR/$tdir.cvsroot
7696         chown $RUNAS_ID $DIR/$tdir.cvsroot
7697
7698         cd $TMP
7699         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
7700
7701         cd /etc/init.d
7702         # some versions of cvs import exit(1) when asked to import links or
7703         # files they can't read.  ignore those files.
7704         local toignore=$(find . -type l -printf '-I %f\n' -o \
7705                          ! -perm /4 -printf '-I %f\n')
7706         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
7707                 $tdir.reposname vtag rtag
7708
7709         cd $DIR
7710         test_mkdir $DIR/$tdir.reposname
7711         chown $RUNAS_ID $DIR/$tdir.reposname
7712         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
7713
7714         cd $DIR/$tdir.reposname
7715         $RUNAS touch foo99
7716         $RUNAS cvs add -m 'addmsg' foo99
7717         $RUNAS cvs update
7718         $RUNAS cvs commit -m 'nomsg' foo99
7719         rm -fr $DIR/$tdir.cvsroot
7720 }
7721 run_test 99 "cvs strange file/directory operations"
7722
7723 test_100() {
7724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7725         [[ "$NETTYPE" =~ tcp ]] ||
7726                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
7727         remote_ost_nodsh && skip "remote OST with nodsh"
7728         remote_mds_nodsh && skip "remote MDS with nodsh"
7729         remote_servers ||
7730                 skip "useless for local single node setup"
7731
7732         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
7733                 [ "$PROT" != "tcp" ] && continue
7734                 RPORT=$(echo $REMOTE | cut -d: -f2)
7735                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
7736
7737                 rc=0
7738                 LPORT=`echo $LOCAL | cut -d: -f2`
7739                 if [ $LPORT -ge 1024 ]; then
7740                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
7741                         netstat -tna
7742                         error_exit "local: $LPORT > 1024, remote: $RPORT"
7743                 fi
7744         done
7745         [ "$rc" = 0 ] || error_exit "privileged port not found" )
7746 }
7747 run_test 100 "check local port using privileged port ==========="
7748
7749 function get_named_value()
7750 {
7751     local tag
7752
7753     tag=$1
7754     while read ;do
7755         line=$REPLY
7756         case $line in
7757         $tag*)
7758             echo $line | sed "s/^$tag[ ]*//"
7759             break
7760             ;;
7761         esac
7762     done
7763 }
7764
7765 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
7766                    awk '/^max_cached_mb/ { print $2 }')
7767
7768 cleanup_101a() {
7769         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
7770         trap 0
7771 }
7772
7773 test_101a() {
7774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7775         [ $MDSCOUNT -ge 2 ] && skip_env "needs < 2 MDTs" #LU-4322
7776
7777         local s
7778         local discard
7779         local nreads=10000
7780         local cache_limit=32
7781
7782         $LCTL set_param -n osc.*-osc*.rpc_stats 0
7783         trap cleanup_101a EXIT
7784         $LCTL set_param -n llite.*.read_ahead_stats 0
7785         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
7786
7787         #
7788         # randomly read 10000 of 64K chunks from file 3x 32MB in size
7789         #
7790         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
7791         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
7792
7793         discard=0
7794         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
7795                 get_named_value 'read but discarded' | cut -d" " -f1); do
7796                         discard=$(($discard + $s))
7797         done
7798         cleanup_101a
7799
7800         if [[ $(($discard * 10)) -gt $nreads ]]; then
7801                 $LCTL get_param osc.*-osc*.rpc_stats
7802                 $LCTL get_param llite.*.read_ahead_stats
7803                 error "too many ($discard) discarded pages"
7804         fi
7805         rm -f $DIR/$tfile || true
7806 }
7807 run_test 101a "check read-ahead for random reads"
7808
7809 setup_test101bc() {
7810         test_mkdir $DIR/$tdir
7811         local ssize=$1
7812         local FILE_LENGTH=$2
7813         STRIPE_OFFSET=0
7814
7815         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
7816
7817         local list=$(comma_list $(osts_nodes))
7818         set_osd_param $list '' read_cache_enable 0
7819         set_osd_param $list '' writethrough_cache_enable 0
7820
7821         trap cleanup_test101bc EXIT
7822         # prepare the read-ahead file
7823         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
7824
7825         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
7826                                 count=$FILE_SIZE_MB 2> /dev/null
7827
7828 }
7829
7830 cleanup_test101bc() {
7831         trap 0
7832         rm -rf $DIR/$tdir
7833         rm -f $DIR/$tfile
7834
7835         local list=$(comma_list $(osts_nodes))
7836         set_osd_param $list '' read_cache_enable 1
7837         set_osd_param $list '' writethrough_cache_enable 1
7838 }
7839
7840 calc_total() {
7841         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
7842 }
7843
7844 ra_check_101() {
7845         local READ_SIZE=$1
7846         local STRIPE_SIZE=$2
7847         local FILE_LENGTH=$3
7848         local RA_INC=1048576
7849         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
7850         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
7851                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
7852         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
7853                         get_named_value 'read but discarded' |
7854                         cut -d" " -f1 | calc_total)
7855         if [[ $DISCARD -gt $discard_limit ]]; then
7856                 $LCTL get_param llite.*.read_ahead_stats
7857                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
7858         else
7859                 echo "Read-ahead success for size ${READ_SIZE}"
7860         fi
7861 }
7862
7863 test_101b() {
7864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7865         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7866
7867         local STRIPE_SIZE=1048576
7868         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
7869
7870         if [ $SLOW == "yes" ]; then
7871                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
7872         else
7873                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
7874         fi
7875
7876         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
7877
7878         # prepare the read-ahead file
7879         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
7880         cancel_lru_locks osc
7881         for BIDX in 2 4 8 16 32 64 128 256
7882         do
7883                 local BSIZE=$((BIDX*4096))
7884                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
7885                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
7886                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
7887                 $LCTL set_param -n llite.*.read_ahead_stats 0
7888                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
7889                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
7890                 cancel_lru_locks osc
7891                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
7892         done
7893         cleanup_test101bc
7894         true
7895 }
7896 run_test 101b "check stride-io mode read-ahead ================="
7897
7898 test_101c() {
7899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7900
7901         local STRIPE_SIZE=1048576
7902         local FILE_LENGTH=$((STRIPE_SIZE*100))
7903         local nreads=10000
7904         local rsize=65536
7905         local osc_rpc_stats
7906
7907         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
7908
7909         cancel_lru_locks osc
7910         $LCTL set_param osc.*.rpc_stats 0
7911         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
7912         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
7913                 local stats=$($LCTL get_param -n $osc_rpc_stats)
7914                 local lines=$(echo "$stats" | awk 'END {print NR;}')
7915                 local size
7916
7917                 if [ $lines -le 20 ]; then
7918                         continue
7919                 fi
7920                 for size in 1 2 4 8; do
7921                         local rpc=$(echo "$stats" |
7922                                     awk '($1 == "'$size':") {print $2; exit; }')
7923                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
7924                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
7925                 done
7926                 echo "$osc_rpc_stats check passed!"
7927         done
7928         cleanup_test101bc
7929         true
7930 }
7931 run_test 101c "check stripe_size aligned read-ahead ================="
7932
7933 set_read_ahead() {
7934         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
7935         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
7936 }
7937
7938 test_101d() {
7939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7940
7941         local file=$DIR/$tfile
7942         local sz_MB=${FILESIZE_101d:-500}
7943         local ra_MB=${READAHEAD_MB:-40}
7944
7945         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
7946         [ $free_MB -lt $sz_MB ] &&
7947                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
7948
7949         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
7950         $LFS setstripe -c -1 $file || error "setstripe failed"
7951
7952         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
7953         echo Cancel LRU locks on lustre client to flush the client cache
7954         cancel_lru_locks osc
7955
7956         echo Disable read-ahead
7957         local old_READAHEAD=$(set_read_ahead 0)
7958
7959         echo Reading the test file $file with read-ahead disabled
7960         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
7961
7962         echo Cancel LRU locks on lustre client to flush the client cache
7963         cancel_lru_locks osc
7964         echo Enable read-ahead with ${ra_MB}MB
7965         set_read_ahead $ra_MB
7966
7967         echo Reading the test file $file with read-ahead enabled
7968         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
7969
7970         echo "read-ahead disabled time read $raOFF"
7971         echo "read-ahead enabled  time read $raON"
7972
7973         set_read_ahead $old_READAHEAD
7974         rm -f $file
7975         wait_delete_completed
7976
7977         [ $raOFF -le 1 -o $raON -lt $raOFF ] ||
7978                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
7979 }
7980 run_test 101d "file read with and without read-ahead enabled"
7981
7982 test_101e() {
7983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7984
7985         local file=$DIR/$tfile
7986         local size_KB=500  #KB
7987         local count=100
7988         local bsize=1024
7989
7990         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
7991         local need_KB=$((count * size_KB))
7992         [[ $free_KB -le $need_KB ]] &&
7993                 skip_env "Need free space $need_KB, have $free_KB"
7994
7995         echo "Creating $count ${size_KB}K test files"
7996         for ((i = 0; i < $count; i++)); do
7997                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
7998         done
7999
8000         echo "Cancel LRU locks on lustre client to flush the client cache"
8001         cancel_lru_locks $OSC
8002
8003         echo "Reset readahead stats"
8004         $LCTL set_param -n llite.*.read_ahead_stats 0
8005
8006         for ((i = 0; i < $count; i++)); do
8007                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
8008         done
8009
8010         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8011                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
8012
8013         for ((i = 0; i < $count; i++)); do
8014                 rm -rf $file.$i 2>/dev/null
8015         done
8016
8017         #10000 means 20% reads are missing in readahead
8018         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
8019 }
8020 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
8021
8022 test_101f() {
8023         which iozone || skip_env "no iozone installed"
8024
8025         local old_debug=$($LCTL get_param debug)
8026         old_debug=${old_debug#*=}
8027         $LCTL set_param debug="reada mmap"
8028
8029         # create a test file
8030         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
8031
8032         echo Cancel LRU locks on lustre client to flush the client cache
8033         cancel_lru_locks osc
8034
8035         echo Reset readahead stats
8036         $LCTL set_param -n llite.*.read_ahead_stats 0
8037
8038         echo mmap read the file with small block size
8039         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
8040                 > /dev/null 2>&1
8041
8042         echo checking missing pages
8043         $LCTL get_param llite.*.read_ahead_stats
8044         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8045                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8046
8047         $LCTL set_param debug="$old_debug"
8048         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
8049         rm -f $DIR/$tfile
8050 }
8051 run_test 101f "check mmap read performance"
8052
8053 test_101g_brw_size_test() {
8054         local mb=$1
8055         local pages=$((mb * 1048576 / PAGE_SIZE))
8056         local file=$DIR/$tfile
8057
8058         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
8059                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
8060         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
8061                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
8062                         return 2
8063         done
8064
8065         stack_trap "rm -f $file" EXIT
8066         $LCTL set_param -n osc.*.rpc_stats=0
8067
8068         # 10 RPCs should be enough for the test
8069         local count=10
8070         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
8071                 { error "dd write ${mb} MB blocks failed"; return 3; }
8072         cancel_lru_locks osc
8073         dd of=/dev/null if=$file bs=${mb}M count=$count ||
8074                 { error "dd write ${mb} MB blocks failed"; return 4; }
8075
8076         # calculate number of full-sized read and write RPCs
8077         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
8078                 sed -n '/pages per rpc/,/^$/p' |
8079                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
8080                 END { print reads,writes }'))
8081         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
8082                 return 5
8083         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
8084                 return 6
8085
8086         return 0
8087 }
8088
8089 test_101g() {
8090         remote_ost_nodsh && skip "remote OST with nodsh"
8091
8092         local rpcs
8093         local osts=$(get_facets OST)
8094         local list=$(comma_list $(osts_nodes))
8095         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8096         local brw_size="obdfilter.*.brw_size"
8097
8098         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8099
8100         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
8101         if [ $OST1_VERSION -ge $(version_code 2.8.52) -o \
8102              \( $OST1_VERSION -ge $(version_code 2.7.17) -a \
8103                 $OST1_VERSION -lt $(version_code 2.7.50) \) ] &&
8104            [ $CLIENT_VERSION -ge $(version_code 2.8.52) -o \
8105              \( $CLIENT_VERSION -ge $(version_code 2.7.17) -a \
8106                 $CLIENT_VERSION -lt $(version_code 2.7.50) \) ]; then
8107                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] && suffix="M"
8108                 if [[ $orig_mb -lt 16 ]]; then
8109                         save_lustre_params $osts "$brw_size" > $p
8110                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
8111                                 error "set 16MB RPC size failed"
8112
8113                         echo "remount client to enable new RPC size"
8114                         remount_client $MOUNT || error "remount_client failed"
8115                 fi
8116
8117                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
8118                 # should be able to set brw_size=12, but no rpc_stats for that
8119                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
8120         fi
8121
8122         test_101g_brw_size_test 4 || error "4MB RPC test failed"
8123
8124         if [[ $orig_mb -lt 16 ]]; then
8125                 restore_lustre_params < $p
8126                 remount_client $MOUNT || error "remount_client restore failed"
8127         fi
8128
8129         rm -f $p $DIR/$tfile
8130 }
8131 run_test 101g "Big bulk(4/16 MiB) readahead"
8132
8133 setup_test102() {
8134         test_mkdir $DIR/$tdir
8135         chown $RUNAS_ID $DIR/$tdir
8136         STRIPE_SIZE=65536
8137         STRIPE_OFFSET=1
8138         STRIPE_COUNT=$OSTCOUNT
8139         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
8140
8141         trap cleanup_test102 EXIT
8142         cd $DIR
8143         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
8144         cd $DIR/$tdir
8145         for num in 1 2 3 4; do
8146                 for count in $(seq 1 $STRIPE_COUNT); do
8147                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
8148                                 local size=`expr $STRIPE_SIZE \* $num`
8149                                 local file=file"$num-$idx-$count"
8150                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
8151                         done
8152                 done
8153         done
8154
8155         cd $DIR
8156         $1 tar cf $TMP/f102.tar $tdir --xattrs
8157 }
8158
8159 cleanup_test102() {
8160         trap 0
8161         rm -f $TMP/f102.tar
8162         rm -rf $DIR/d0.sanity/d102
8163 }
8164
8165 test_102a() {
8166         [ "$UID" != 0 ] && skip "must run as root"
8167         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
8168                 skip_env "must have user_xattr"
8169
8170         [ -z "$(which setfattr 2>/dev/null)" ] &&
8171                 skip_env "could not find setfattr"
8172
8173         local testfile=$DIR/$tfile
8174
8175         touch $testfile
8176         echo "set/get xattr..."
8177         setfattr -n trusted.name1 -v value1 $testfile ||
8178                 error "setfattr -n trusted.name1=value1 $testfile failed"
8179         getfattr -n trusted.name1 $testfile 2> /dev/null |
8180           grep "trusted.name1=.value1" ||
8181                 error "$testfile missing trusted.name1=value1"
8182
8183         setfattr -n user.author1 -v author1 $testfile ||
8184                 error "setfattr -n user.author1=author1 $testfile failed"
8185         getfattr -n user.author1 $testfile 2> /dev/null |
8186           grep "user.author1=.author1" ||
8187                 error "$testfile missing trusted.author1=author1"
8188
8189         echo "listxattr..."
8190         setfattr -n trusted.name2 -v value2 $testfile ||
8191                 error "$testfile unable to set trusted.name2"
8192         setfattr -n trusted.name3 -v value3 $testfile ||
8193                 error "$testfile unable to set trusted.name3"
8194         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
8195             grep "trusted.name" | wc -l) -eq 3 ] ||
8196                 error "$testfile missing 3 trusted.name xattrs"
8197
8198         setfattr -n user.author2 -v author2 $testfile ||
8199                 error "$testfile unable to set user.author2"
8200         setfattr -n user.author3 -v author3 $testfile ||
8201                 error "$testfile unable to set user.author3"
8202         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
8203             grep "user.author" | wc -l) -eq 3 ] ||
8204                 error "$testfile missing 3 user.author xattrs"
8205
8206         echo "remove xattr..."
8207         setfattr -x trusted.name1 $testfile ||
8208                 error "$testfile error deleting trusted.name1"
8209         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
8210                 error "$testfile did not delete trusted.name1 xattr"
8211
8212         setfattr -x user.author1 $testfile ||
8213                 error "$testfile error deleting user.author1"
8214         echo "set lustre special xattr ..."
8215         $LFS setstripe -c1 $testfile
8216         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
8217                 awk -F "=" '/trusted.lov/ { print $2 }' )
8218         setfattr -n "trusted.lov" -v $lovea $testfile ||
8219                 error "$testfile doesn't ignore setting trusted.lov again"
8220         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
8221                 error "$testfile allow setting invalid trusted.lov"
8222         rm -f $testfile
8223 }
8224 run_test 102a "user xattr test =================================="
8225
8226 test_102b() {
8227         [ -z "$(which setfattr 2>/dev/null)" ] &&
8228                 skip_env "could not find setfattr"
8229         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8230
8231         # b10930: get/set/list trusted.lov xattr
8232         echo "get/set/list trusted.lov xattr ..."
8233         local testfile=$DIR/$tfile
8234         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8235                 error "setstripe failed"
8236         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
8237                 error "getstripe failed"
8238         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
8239                 error "can't get trusted.lov from $testfile"
8240
8241         local testfile2=${testfile}2
8242         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
8243                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
8244
8245         $MCREATE $testfile2
8246         setfattr -n trusted.lov -v $value $testfile2
8247         local stripe_size=$($LFS getstripe -S $testfile2)
8248         local stripe_count=$($LFS getstripe -c $testfile2)
8249         [[ $stripe_size -eq 65536 ]] ||
8250                 error "stripe size $stripe_size != 65536"
8251         [[ $stripe_count -eq $STRIPECOUNT ]] ||
8252                 error "stripe count $stripe_count != $STRIPECOUNT"
8253         rm -f $DIR/$tfile
8254 }
8255 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
8256
8257 test_102c() {
8258         [ -z "$(which setfattr 2>/dev/null)" ] &&
8259                 skip_env "could not find setfattr"
8260         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8261
8262         # b10930: get/set/list lustre.lov xattr
8263         echo "get/set/list lustre.lov xattr ..."
8264         test_mkdir $DIR/$tdir
8265         chown $RUNAS_ID $DIR/$tdir
8266         local testfile=$DIR/$tdir/$tfile
8267         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8268                 error "setstripe failed"
8269         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
8270                 error "getstripe failed"
8271         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
8272         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
8273
8274         local testfile2=${testfile}2
8275         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
8276                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
8277
8278         $RUNAS $MCREATE $testfile2
8279         $RUNAS setfattr -n lustre.lov -v $value $testfile2
8280         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
8281         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
8282         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
8283         [ $stripe_count -eq $STRIPECOUNT ] ||
8284                 error "stripe count $stripe_count != $STRIPECOUNT"
8285 }
8286 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
8287
8288 compare_stripe_info1() {
8289         local stripe_index_all_zero=true
8290
8291         for num in 1 2 3 4; do
8292                 for count in $(seq 1 $STRIPE_COUNT); do
8293                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
8294                                 local size=$((STRIPE_SIZE * num))
8295                                 local file=file"$num-$offset-$count"
8296                                 stripe_size=$($LFS getstripe -S $PWD/$file)
8297                                 [[ $stripe_size -ne $size ]] &&
8298                                     error "$file: size $stripe_size != $size"
8299                                 stripe_count=$($LFS getstripe -c $PWD/$file)
8300                                 # allow fewer stripes to be created, ORI-601
8301                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
8302                                     error "$file: count $stripe_count != $count"
8303                                 stripe_index=$($LFS getstripe -i $PWD/$file)
8304                                 [[ $stripe_index -ne 0 ]] &&
8305                                         stripe_index_all_zero=false
8306                         done
8307                 done
8308         done
8309         $stripe_index_all_zero &&
8310                 error "all files are being extracted starting from OST index 0"
8311         return 0
8312 }
8313
8314 have_xattrs_include() {
8315         tar --help | grep -q xattrs-include &&
8316                 echo --xattrs-include="lustre.*"
8317 }
8318
8319 test_102d() {
8320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8321         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8322
8323         XINC=$(have_xattrs_include)
8324         setup_test102
8325         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8326         cd $DIR/$tdir/$tdir
8327         compare_stripe_info1
8328 }
8329 run_test 102d "tar restore stripe info from tarfile,not keep osts"
8330
8331 test_102f() {
8332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8333         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8334
8335         XINC=$(have_xattrs_include)
8336         setup_test102
8337         test_mkdir $DIR/$tdir.restore
8338         cd $DIR
8339         tar cf - --xattrs $tdir | tar xf - \
8340                 -C $DIR/$tdir.restore --xattrs $XINC
8341         cd $DIR/$tdir.restore/$tdir
8342         compare_stripe_info1
8343 }
8344 run_test 102f "tar copy files, not keep osts"
8345
8346 grow_xattr() {
8347         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
8348                 skip "must have user_xattr"
8349         [ -z "$(which setfattr 2>/dev/null)" ] &&
8350                 skip_env "could not find setfattr"
8351         [ -z "$(which getfattr 2>/dev/null)" ] &&
8352                 skip_env "could not find getfattr"
8353
8354         local xsize=${1:-1024}  # in bytes
8355         local file=$DIR/$tfile
8356         local value="$(generate_string $xsize)"
8357         local xbig=trusted.big
8358         local toobig=$2
8359
8360         touch $file
8361         log "save $xbig on $file"
8362         if [ -z "$toobig" ]
8363         then
8364                 setfattr -n $xbig -v $value $file ||
8365                         error "saving $xbig on $file failed"
8366         else
8367                 setfattr -n $xbig -v $value $file &&
8368                         error "saving $xbig on $file succeeded"
8369                 return 0
8370         fi
8371
8372         local orig=$(get_xattr_value $xbig $file)
8373         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
8374
8375         local xsml=trusted.sml
8376         log "save $xsml on $file"
8377         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
8378
8379         local new=$(get_xattr_value $xbig $file)
8380         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
8381
8382         log "grow $xsml on $file"
8383         setfattr -n $xsml -v "$value" $file ||
8384                 error "growing $xsml on $file failed"
8385
8386         new=$(get_xattr_value $xbig $file)
8387         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
8388         log "$xbig still valid after growing $xsml"
8389
8390         rm -f $file
8391 }
8392
8393 test_102h() { # bug 15777
8394         grow_xattr 1024
8395 }
8396 run_test 102h "grow xattr from inside inode to external block"
8397
8398 test_102ha() {
8399         large_xattr_enabled || skip_env "ea_inode feature disabled"
8400
8401         echo "setting xattr of max xattr size: $(max_xattr_size)"
8402         grow_xattr $(max_xattr_size)
8403
8404         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
8405         echo "This should fail:"
8406         grow_xattr $(($(max_xattr_size) + 10)) 1
8407 }
8408 run_test 102ha "grow xattr from inside inode to external inode"
8409
8410 test_102i() { # bug 17038
8411         [ -z "$(which getfattr 2>/dev/null)" ] &&
8412                 skip "could not find getfattr"
8413
8414         touch $DIR/$tfile
8415         ln -s $DIR/$tfile $DIR/${tfile}link
8416         getfattr -n trusted.lov $DIR/$tfile ||
8417                 error "lgetxattr on $DIR/$tfile failed"
8418         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
8419                 grep -i "no such attr" ||
8420                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
8421         rm -f $DIR/$tfile $DIR/${tfile}link
8422 }
8423 run_test 102i "lgetxattr test on symbolic link ============"
8424
8425 test_102j() {
8426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8427         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8428
8429         XINC=$(have_xattrs_include)
8430         setup_test102 "$RUNAS"
8431         chown $RUNAS_ID $DIR/$tdir
8432         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8433         cd $DIR/$tdir/$tdir
8434         compare_stripe_info1 "$RUNAS"
8435 }
8436 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
8437
8438 test_102k() {
8439         [ -z "$(which setfattr 2>/dev/null)" ] &&
8440                 skip "could not find setfattr"
8441
8442         touch $DIR/$tfile
8443         # b22187 just check that does not crash for regular file.
8444         setfattr -n trusted.lov $DIR/$tfile
8445         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
8446         local test_kdir=$DIR/$tdir
8447         test_mkdir $test_kdir
8448         local default_size=$($LFS getstripe -S $test_kdir)
8449         local default_count=$($LFS getstripe -c $test_kdir)
8450         local default_offset=$($LFS getstripe -i $test_kdir)
8451         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
8452                 error 'dir setstripe failed'
8453         setfattr -n trusted.lov $test_kdir
8454         local stripe_size=$($LFS getstripe -S $test_kdir)
8455         local stripe_count=$($LFS getstripe -c $test_kdir)
8456         local stripe_offset=$($LFS getstripe -i $test_kdir)
8457         [ $stripe_size -eq $default_size ] ||
8458                 error "stripe size $stripe_size != $default_size"
8459         [ $stripe_count -eq $default_count ] ||
8460                 error "stripe count $stripe_count != $default_count"
8461         [ $stripe_offset -eq $default_offset ] ||
8462                 error "stripe offset $stripe_offset != $default_offset"
8463         rm -rf $DIR/$tfile $test_kdir
8464 }
8465 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
8466
8467 test_102l() {
8468         [ -z "$(which getfattr 2>/dev/null)" ] &&
8469                 skip "could not find getfattr"
8470
8471         # LU-532 trusted. xattr is invisible to non-root
8472         local testfile=$DIR/$tfile
8473
8474         touch $testfile
8475
8476         echo "listxattr as user..."
8477         chown $RUNAS_ID $testfile
8478         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
8479             grep -q "trusted" &&
8480                 error "$testfile trusted xattrs are user visible"
8481
8482         return 0;
8483 }
8484 run_test 102l "listxattr size test =================================="
8485
8486 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
8487         local path=$DIR/$tfile
8488         touch $path
8489
8490         listxattr_size_check $path || error "listattr_size_check $path failed"
8491 }
8492 run_test 102m "Ensure listxattr fails on small bufffer ========"
8493
8494 cleanup_test102
8495
8496 getxattr() { # getxattr path name
8497         # Return the base64 encoding of the value of xattr name on path.
8498         local path=$1
8499         local name=$2
8500
8501         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
8502         # file: $path
8503         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8504         #
8505         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8506
8507         getfattr --absolute-names --encoding=base64 --name=$name $path |
8508                 awk -F= -v name=$name '$1 == name {
8509                         print substr($0, index($0, "=") + 1);
8510         }'
8511 }
8512
8513 test_102n() { # LU-4101 mdt: protect internal xattrs
8514         [ -z "$(which setfattr 2>/dev/null)" ] &&
8515                 skip "could not find setfattr"
8516         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
8517         then
8518                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
8519         fi
8520
8521         local file0=$DIR/$tfile.0
8522         local file1=$DIR/$tfile.1
8523         local xattr0=$TMP/$tfile.0
8524         local xattr1=$TMP/$tfile.1
8525         local namelist="lov lma lmv link fid version som hsm"
8526         local name
8527         local value
8528
8529         rm -rf $file0 $file1 $xattr0 $xattr1
8530         touch $file0 $file1
8531
8532         # Get 'before' xattrs of $file1.
8533         getfattr --absolute-names --dump --match=- $file1 > $xattr0
8534
8535         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
8536                 namelist+=" lfsck_namespace"
8537         for name in $namelist; do
8538                 # Try to copy xattr from $file0 to $file1.
8539                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
8540
8541                 setfattr --name=trusted.$name --value="$value" $file1 ||
8542                         error "setxattr 'trusted.$name' failed"
8543
8544                 # Try to set a garbage xattr.
8545                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
8546
8547                 if [[ x$name == "xlov" ]]; then
8548                         setfattr --name=trusted.lov --value="$value" $file1 &&
8549                         error "setxattr invalid 'trusted.lov' success"
8550                 else
8551                         setfattr --name=trusted.$name --value="$value" $file1 ||
8552                                 error "setxattr invalid 'trusted.$name' failed"
8553                 fi
8554
8555                 # Try to remove the xattr from $file1. We don't care if this
8556                 # appears to succeed or fail, we just don't want there to be
8557                 # any changes or crashes.
8558                 setfattr --remove=$trusted.$name $file1 2> /dev/null
8559         done
8560
8561         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
8562         then
8563                 name="lfsck_ns"
8564                 # Try to copy xattr from $file0 to $file1.
8565                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
8566
8567                 setfattr --name=trusted.$name --value="$value" $file1 ||
8568                         error "setxattr 'trusted.$name' failed"
8569
8570                 # Try to set a garbage xattr.
8571                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
8572
8573                 setfattr --name=trusted.$name --value="$value" $file1 ||
8574                         error "setxattr 'trusted.$name' failed"
8575
8576                 # Try to remove the xattr from $file1. We don't care if this
8577                 # appears to succeed or fail, we just don't want there to be
8578                 # any changes or crashes.
8579                 setfattr --remove=$trusted.$name $file1 2> /dev/null
8580         fi
8581
8582         # Get 'after' xattrs of file1.
8583         getfattr --absolute-names --dump --match=- $file1 > $xattr1
8584
8585         if ! diff $xattr0 $xattr1; then
8586                 error "before and after xattrs of '$file1' differ"
8587         fi
8588
8589         rm -rf $file0 $file1 $xattr0 $xattr1
8590
8591         return 0
8592 }
8593 run_test 102n "silently ignore setxattr on internal trusted xattrs"
8594
8595 test_102p() { # LU-4703 setxattr did not check ownership
8596         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
8597                 skip "MDS needs to be at least 2.5.56"
8598
8599         local testfile=$DIR/$tfile
8600
8601         touch $testfile
8602
8603         echo "setfacl as user..."
8604         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
8605         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
8606
8607         echo "setfattr as user..."
8608         setfacl -m "u:$RUNAS_ID:---" $testfile
8609         $RUNAS setfattr -x system.posix_acl_access $testfile
8610         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
8611 }
8612 run_test 102p "check setxattr(2) correctly fails without permission"
8613
8614 test_102q() {
8615         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
8616                 skip "MDS needs to be at least 2.6.92"
8617
8618         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
8619 }
8620 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
8621
8622 test_102r() {
8623         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
8624                 skip "MDS needs to be at least 2.6.93"
8625
8626         touch $DIR/$tfile || error "touch"
8627         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
8628         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
8629         rm $DIR/$tfile || error "rm"
8630
8631         #normal directory
8632         mkdir -p $DIR/$tdir || error "mkdir"
8633         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
8634         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
8635         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
8636                 error "$testfile error deleting user.author1"
8637         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
8638                 grep "user.$(basename $tdir)" &&
8639                 error "$tdir did not delete user.$(basename $tdir)"
8640         rmdir $DIR/$tdir || error "rmdir"
8641
8642         #striped directory
8643         test_mkdir $DIR/$tdir
8644         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
8645         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
8646         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
8647                 error "$testfile error deleting user.author1"
8648         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
8649                 grep "user.$(basename $tdir)" &&
8650                 error "$tdir did not delete user.$(basename $tdir)"
8651         rmdir $DIR/$tdir || error "rm striped dir"
8652 }
8653 run_test 102r "set EAs with empty values"
8654
8655 test_102s() {
8656         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
8657                 skip "MDS needs to be at least 2.11.52"
8658
8659         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
8660
8661         save_lustre_params client "llite.*.xattr_cache" > $save
8662
8663         for cache in 0 1; do
8664                 lctl set_param llite.*.xattr_cache=$cache
8665
8666                 rm -f $DIR/$tfile
8667                 touch $DIR/$tfile || error "touch"
8668                 for prefix in lustre security system trusted user; do
8669                         # Note getxattr() may fail with 'Operation not
8670                         # supported' or 'No such attribute' depending
8671                         # on prefix and cache.
8672                         getfattr -n $prefix.n102s $DIR/$tfile &&
8673                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
8674                 done
8675         done
8676
8677         restore_lustre_params < $save
8678 }
8679 run_test 102s "getting nonexistent xattrs should fail"
8680
8681 test_102t() {
8682         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
8683                 skip "MDS needs to be at least 2.11.52"
8684
8685         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
8686
8687         save_lustre_params client "llite.*.xattr_cache" > $save
8688
8689         for cache in 0 1; do
8690                 lctl set_param llite.*.xattr_cache=$cache
8691
8692                 for buf_size in 0 256; do
8693                         rm -f $DIR/$tfile
8694                         touch $DIR/$tfile || error "touch"
8695                         setfattr -n user.multiop $DIR/$tfile
8696                         $MULTIOP $DIR/$tfile oa$buf_size ||
8697                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
8698                 done
8699         done
8700
8701         restore_lustre_params < $save
8702 }
8703 run_test 102t "zero length xattr values handled correctly"
8704
8705 run_acl_subtest()
8706 {
8707     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
8708     return $?
8709 }
8710
8711 test_103a() {
8712         [ "$UID" != 0 ] && skip "must run as root"
8713         $GSS && skip_env "could not run under gss"
8714         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
8715                 skip_env "must have acl enabled"
8716         [ -z "$(which setfacl 2>/dev/null)" ] &&
8717                 skip_env "could not find setfacl"
8718         remote_mds_nodsh && skip "remote MDS with nodsh"
8719
8720         gpasswd -a daemon bin                           # LU-5641
8721         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
8722
8723         declare -a identity_old
8724
8725         for num in $(seq $MDSCOUNT); do
8726                 switch_identity $num true || identity_old[$num]=$?
8727         done
8728
8729         SAVE_UMASK=$(umask)
8730         umask 0022
8731         mkdir -p $DIR/$tdir
8732         cd $DIR/$tdir
8733
8734         echo "performing cp ..."
8735         run_acl_subtest cp || error "run_acl_subtest cp failed"
8736         echo "performing getfacl-noacl..."
8737         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
8738         echo "performing misc..."
8739         run_acl_subtest misc || error  "misc test failed"
8740         echo "performing permissions..."
8741         run_acl_subtest permissions || error "permissions failed"
8742         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
8743         if [ $MDS1_VERSION -gt $(version_code 2.8.55) -o \
8744              \( $MDS1_VERSION -lt $(version_code 2.6) -a \
8745              $MDS1_VERSION -ge $(version_code 2.5.29) \) ]
8746         then
8747                 echo "performing permissions xattr..."
8748                 run_acl_subtest permissions_xattr ||
8749                         error "permissions_xattr failed"
8750         fi
8751         echo "performing setfacl..."
8752         run_acl_subtest setfacl || error  "setfacl test failed"
8753
8754         # inheritance test got from HP
8755         echo "performing inheritance..."
8756         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
8757         chmod +x make-tree || error "chmod +x failed"
8758         run_acl_subtest inheritance || error "inheritance test failed"
8759         rm -f make-tree
8760
8761         echo "LU-974 ignore umask when acl is enabled..."
8762         run_acl_subtest 974 || error "LU-974 umask test failed"
8763         if [ $MDSCOUNT -ge 2 ]; then
8764                 run_acl_subtest 974_remote ||
8765                         error "LU-974 umask test failed under remote dir"
8766         fi
8767
8768         echo "LU-2561 newly created file is same size as directory..."
8769         if [ "$mds1_FSTYPE" != "zfs" ]; then
8770                 run_acl_subtest 2561 || error "LU-2561 test failed"
8771         else
8772                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
8773         fi
8774
8775         run_acl_subtest 4924 || error "LU-4924 test failed"
8776
8777         cd $SAVE_PWD
8778         umask $SAVE_UMASK
8779
8780         for num in $(seq $MDSCOUNT); do
8781                 if [ "${identity_old[$num]}" = 1 ]; then
8782                         switch_identity $num false || identity_old[$num]=$?
8783                 fi
8784         done
8785 }
8786 run_test 103a "acl test"
8787
8788 test_103b() {
8789         declare -a pids
8790         local U
8791
8792         for U in {0..511}; do
8793                 {
8794                 local O=$(printf "%04o" $U)
8795
8796                 umask $(printf "%04o" $((511 ^ $O)))
8797                 $LFS setstripe -c 1 $DIR/$tfile.s$O
8798                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
8799
8800                 (( $S == ($O & 0666) )) ||
8801                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
8802
8803                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
8804                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
8805                 (( $S == ($O & 0666) )) ||
8806                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
8807
8808                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
8809                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
8810                 (( $S == ($O & 0666) )) ||
8811                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
8812                 rm -f $DIR/$tfile.[smp]$0
8813                 } &
8814                 local pid=$!
8815
8816                 # limit the concurrently running threads to 64. LU-11878
8817                 local idx=$((U % 64))
8818                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
8819                 pids[idx]=$pid
8820         done
8821         wait
8822 }
8823 run_test 103b "umask lfs setstripe"
8824
8825 test_103c() {
8826         mkdir -p $DIR/$tdir
8827         cp -rp $DIR/$tdir $DIR/$tdir.bak
8828
8829         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
8830                 error "$DIR/$tdir shouldn't contain default ACL"
8831         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
8832                 error "$DIR/$tdir.bak shouldn't contain default ACL"
8833         true
8834 }
8835 run_test 103c "'cp -rp' won't set empty acl"
8836
8837 test_104a() {
8838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8839
8840         touch $DIR/$tfile
8841         lfs df || error "lfs df failed"
8842         lfs df -ih || error "lfs df -ih failed"
8843         lfs df -h $DIR || error "lfs df -h $DIR failed"
8844         lfs df -i $DIR || error "lfs df -i $DIR failed"
8845         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
8846         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
8847
8848         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
8849         lctl --device %$OSC deactivate
8850         lfs df || error "lfs df with deactivated OSC failed"
8851         lctl --device %$OSC activate
8852         # wait the osc back to normal
8853         wait_osc_import_ready client ost
8854
8855         lfs df || error "lfs df with reactivated OSC failed"
8856         rm -f $DIR/$tfile
8857 }
8858 run_test 104a "lfs df [-ih] [path] test ========================="
8859
8860 test_104b() {
8861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8862         [ $RUNAS_ID -eq $UID ] &&
8863                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8864
8865         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
8866                         grep "Permission denied" | wc -l)))
8867         if [ $denied_cnt -ne 0 ]; then
8868                 error "lfs check servers test failed"
8869         fi
8870 }
8871 run_test 104b "$RUNAS lfs check servers test ===================="
8872
8873 test_105a() {
8874         # doesn't work on 2.4 kernels
8875         touch $DIR/$tfile
8876         if $(flock_is_enabled); then
8877                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
8878         else
8879                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
8880         fi
8881         rm -f $DIR/$tfile
8882 }
8883 run_test 105a "flock when mounted without -o flock test ========"
8884
8885 test_105b() {
8886         touch $DIR/$tfile
8887         if $(flock_is_enabled); then
8888                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
8889         else
8890                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
8891         fi
8892         rm -f $DIR/$tfile
8893 }
8894 run_test 105b "fcntl when mounted without -o flock test ========"
8895
8896 test_105c() {
8897         touch $DIR/$tfile
8898         if $(flock_is_enabled); then
8899                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
8900         else
8901                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
8902         fi
8903         rm -f $DIR/$tfile
8904 }
8905 run_test 105c "lockf when mounted without -o flock test"
8906
8907 test_105d() { # bug 15924
8908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8909
8910         test_mkdir $DIR/$tdir
8911         flock_is_enabled || skip_env "mount w/o flock enabled"
8912         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
8913         $LCTL set_param fail_loc=0x80000315
8914         flocks_test 2 $DIR/$tdir
8915 }
8916 run_test 105d "flock race (should not freeze) ========"
8917
8918 test_105e() { # bug 22660 && 22040
8919         flock_is_enabled || skip_env "mount w/o flock enabled"
8920
8921         touch $DIR/$tfile
8922         flocks_test 3 $DIR/$tfile
8923 }
8924 run_test 105e "Two conflicting flocks from same process"
8925
8926 test_106() { #bug 10921
8927         test_mkdir $DIR/$tdir
8928         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
8929         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
8930 }
8931 run_test 106 "attempt exec of dir followed by chown of that dir"
8932
8933 test_107() {
8934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8935
8936         CDIR=`pwd`
8937         local file=core
8938
8939         cd $DIR
8940         rm -f $file
8941
8942         local save_pattern=$(sysctl -n kernel.core_pattern)
8943         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
8944         sysctl -w kernel.core_pattern=$file
8945         sysctl -w kernel.core_uses_pid=0
8946
8947         ulimit -c unlimited
8948         sleep 60 &
8949         SLEEPPID=$!
8950
8951         sleep 1
8952
8953         kill -s 11 $SLEEPPID
8954         wait $SLEEPPID
8955         if [ -e $file ]; then
8956                 size=`stat -c%s $file`
8957                 [ $size -eq 0 ] && error "Fail to create core file $file"
8958         else
8959                 error "Fail to create core file $file"
8960         fi
8961         rm -f $file
8962         sysctl -w kernel.core_pattern=$save_pattern
8963         sysctl -w kernel.core_uses_pid=$save_uses_pid
8964         cd $CDIR
8965 }
8966 run_test 107 "Coredump on SIG"
8967
8968 test_110() {
8969         test_mkdir $DIR/$tdir
8970         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
8971         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
8972                 error "mkdir with 256 char should fail, but did not"
8973         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
8974                 error "create with 255 char failed"
8975         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
8976                 error "create with 256 char should fail, but did not"
8977
8978         ls -l $DIR/$tdir
8979         rm -rf $DIR/$tdir
8980 }
8981 run_test 110 "filename length checking"
8982
8983 #
8984 # Purpose: To verify dynamic thread (OSS) creation.
8985 #
8986 test_115() {
8987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8988         remote_ost_nodsh && skip "remote OST with nodsh"
8989
8990         # Lustre does not stop service threads once they are started.
8991         # Reset number of running threads to default.
8992         stopall
8993         setupall
8994
8995         local OSTIO_pre
8996         local save_params="$TMP/sanity-$TESTNAME.parameters"
8997
8998         # Get ll_ost_io count before I/O
8999         OSTIO_pre=$(do_facet ost1 \
9000                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
9001         # Exit if lustre is not running (ll_ost_io not running).
9002         [ -z "$OSTIO_pre" ] && error "no OSS threads"
9003
9004         echo "Starting with $OSTIO_pre threads"
9005         local thread_max=$((OSTIO_pre * 2))
9006         local rpc_in_flight=$((thread_max * 2))
9007         # Number of I/O Process proposed to be started.
9008         local nfiles
9009         local facets=$(get_facets OST)
9010
9011         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
9012         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
9013
9014         # Set in_flight to $rpc_in_flight
9015         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
9016                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
9017         nfiles=${rpc_in_flight}
9018         # Set ost thread_max to $thread_max
9019         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
9020
9021         # 5 Minutes should be sufficient for max number of OSS
9022         # threads(thread_max) to be created.
9023         local timeout=300
9024
9025         # Start I/O.
9026         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
9027         test_mkdir $DIR/$tdir
9028         for i in $(seq $nfiles); do
9029                 local file=$DIR/$tdir/${tfile}-$i
9030                 $LFS setstripe -c -1 -i 0 $file
9031                 ($WTL $file $timeout)&
9032         done
9033
9034         # I/O Started - Wait for thread_started to reach thread_max or report
9035         # error if thread_started is more than thread_max.
9036         echo "Waiting for thread_started to reach thread_max"
9037         local thread_started=0
9038         local end_time=$((SECONDS + timeout))
9039
9040         while [ $SECONDS -le $end_time ] ; do
9041                 echo -n "."
9042                 # Get ost i/o thread_started count.
9043                 thread_started=$(do_facet ost1 \
9044                         "$LCTL get_param \
9045                         ost.OSS.ost_io.threads_started | cut -d= -f2")
9046                 # Break out if thread_started is equal/greater than thread_max
9047                 if [[ $thread_started -ge $thread_max ]]; then
9048                         echo ll_ost_io thread_started $thread_started, \
9049                                 equal/greater than thread_max $thread_max
9050                         break
9051                 fi
9052                 sleep 1
9053         done
9054
9055         # Cleanup - We have the numbers, Kill i/o jobs if running.
9056         jobcount=($(jobs -p))
9057         for i in $(seq 0 $((${#jobcount[@]}-1)))
9058         do
9059                 kill -9 ${jobcount[$i]}
9060                 if [ $? -ne 0 ] ; then
9061                         echo Warning: \
9062                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
9063                 fi
9064         done
9065
9066         # Cleanup files left by WTL binary.
9067         for i in $(seq $nfiles); do
9068                 local file=$DIR/$tdir/${tfile}-$i
9069                 rm -rf $file
9070                 if [ $? -ne 0 ] ; then
9071                         echo "Warning: Failed to delete file $file"
9072                 fi
9073         done
9074
9075         restore_lustre_params <$save_params
9076         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
9077
9078         # Error out if no new thread has started or Thread started is greater
9079         # than thread max.
9080         if [[ $thread_started -le $OSTIO_pre ||
9081                         $thread_started -gt $thread_max ]]; then
9082                 error "ll_ost_io: thread_started $thread_started" \
9083                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
9084                       "No new thread started or thread started greater " \
9085                       "than thread_max."
9086         fi
9087 }
9088 run_test 115 "verify dynamic thread creation===================="
9089
9090 free_min_max () {
9091         wait_delete_completed
9092         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
9093         echo "OST kbytes available: ${AVAIL[@]}"
9094         MAXV=${AVAIL[0]}
9095         MAXI=0
9096         MINV=${AVAIL[0]}
9097         MINI=0
9098         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
9099                 #echo OST $i: ${AVAIL[i]}kb
9100                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
9101                         MAXV=${AVAIL[i]}
9102                         MAXI=$i
9103                 fi
9104                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
9105                         MINV=${AVAIL[i]}
9106                         MINI=$i
9107                 fi
9108         done
9109         echo "Min free space: OST $MINI: $MINV"
9110         echo "Max free space: OST $MAXI: $MAXV"
9111 }
9112
9113 test_116a() { # was previously test_116()
9114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9115         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9116         remote_mds_nodsh && skip "remote MDS with nodsh"
9117
9118         echo -n "Free space priority "
9119         do_facet $SINGLEMDS lctl get_param -n lo*.*-mdtlov.qos_prio_free |
9120                 head -n1
9121         declare -a AVAIL
9122         free_min_max
9123
9124         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
9125         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
9126         trap simple_cleanup_common EXIT
9127
9128         # Check if we need to generate uneven OSTs
9129         test_mkdir -p $DIR/$tdir/OST${MINI}
9130         local FILL=$((MINV / 4))
9131         local DIFF=$((MAXV - MINV))
9132         local DIFF2=$((DIFF * 100 / MINV))
9133
9134         local threshold=$(do_facet $SINGLEMDS \
9135                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
9136         threshold=${threshold%%%}
9137         echo -n "Check for uneven OSTs: "
9138         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
9139
9140         if [[ $DIFF2 -gt $threshold ]]; then
9141                 echo "ok"
9142                 echo "Don't need to fill OST$MINI"
9143         else
9144                 # generate uneven OSTs. Write 2% over the QOS threshold value
9145                 echo "no"
9146                 DIFF=$((threshold - DIFF2 + 2))
9147                 DIFF2=$((MINV * DIFF / 100))
9148                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
9149                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
9150                         error "setstripe failed"
9151                 DIFF=$((DIFF2 / 2048))
9152                 i=0
9153                 while [ $i -lt $DIFF ]; do
9154                         i=$((i + 1))
9155                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
9156                                 bs=2M count=1 2>/dev/null
9157                         echo -n .
9158                 done
9159                 echo .
9160                 sync
9161                 sleep_maxage
9162                 free_min_max
9163         fi
9164
9165         DIFF=$((MAXV - MINV))
9166         DIFF2=$((DIFF * 100 / MINV))
9167         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
9168         if [ $DIFF2 -gt $threshold ]; then
9169                 echo "ok"
9170         else
9171                 echo "failed - QOS mode won't be used"
9172                 simple_cleanup_common
9173                 skip "QOS imbalance criteria not met"
9174         fi
9175
9176         MINI1=$MINI
9177         MINV1=$MINV
9178         MAXI1=$MAXI
9179         MAXV1=$MAXV
9180
9181         # now fill using QOS
9182         $LFS setstripe -c 1 $DIR/$tdir
9183         FILL=$((FILL / 200))
9184         if [ $FILL -gt 600 ]; then
9185                 FILL=600
9186         fi
9187         echo "writing $FILL files to QOS-assigned OSTs"
9188         i=0
9189         while [ $i -lt $FILL ]; do
9190                 i=$((i + 1))
9191                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
9192                         count=1 2>/dev/null
9193                 echo -n .
9194         done
9195         echo "wrote $i 200k files"
9196         sync
9197         sleep_maxage
9198
9199         echo "Note: free space may not be updated, so measurements might be off"
9200         free_min_max
9201         DIFF2=$((MAXV - MINV))
9202         echo "free space delta: orig $DIFF final $DIFF2"
9203         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
9204         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
9205         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
9206         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
9207         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
9208         if [[ $DIFF -gt 0 ]]; then
9209                 FILL=$((DIFF2 * 100 / DIFF - 100))
9210                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
9211         fi
9212
9213         # Figure out which files were written where
9214         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9215                awk '/'$MINI1': / {print $2; exit}')
9216         echo $UUID
9217         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9218         echo "$MINC files created on smaller OST $MINI1"
9219         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9220                awk '/'$MAXI1': / {print $2; exit}')
9221         echo $UUID
9222         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9223         echo "$MAXC files created on larger OST $MAXI1"
9224         if [[ $MINC -gt 0 ]]; then
9225                 FILL=$((MAXC * 100 / MINC - 100))
9226                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
9227         fi
9228         [[ $MAXC -gt $MINC ]] ||
9229                 error_ignore LU-9 "stripe QOS didn't balance free space"
9230         simple_cleanup_common
9231 }
9232 run_test 116a "stripe QOS: free space balance ==================="
9233
9234 test_116b() { # LU-2093
9235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9236         remote_mds_nodsh && skip "remote MDS with nodsh"
9237
9238 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
9239         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
9240                        lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
9241         [ -z "$old_rr" ] && skip "no QOS"
9242         do_facet $SINGLEMDS lctl set_param \
9243                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
9244         mkdir -p $DIR/$tdir
9245         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
9246         createmany -o $DIR/$tdir/f- 20 || error "can't create"
9247         do_facet $SINGLEMDS lctl set_param fail_loc=0
9248         rm -rf $DIR/$tdir
9249         do_facet $SINGLEMDS lctl set_param \
9250                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
9251 }
9252 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
9253
9254 test_117() # bug 10891
9255 {
9256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9257
9258         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
9259         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
9260         lctl set_param fail_loc=0x21e
9261         > $DIR/$tfile || error "truncate failed"
9262         lctl set_param fail_loc=0
9263         echo "Truncate succeeded."
9264         rm -f $DIR/$tfile
9265 }
9266 run_test 117 "verify osd extend =========="
9267
9268 NO_SLOW_RESENDCOUNT=4
9269 export OLD_RESENDCOUNT=""
9270 set_resend_count () {
9271         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
9272         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
9273         lctl set_param -n $PROC_RESENDCOUNT $1
9274         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
9275 }
9276
9277 # for reduce test_118* time (b=14842)
9278 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9279
9280 # Reset async IO behavior after error case
9281 reset_async() {
9282         FILE=$DIR/reset_async
9283
9284         # Ensure all OSCs are cleared
9285         $LFS setstripe -c -1 $FILE
9286         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
9287         sync
9288         rm $FILE
9289 }
9290
9291 test_118a() #bug 11710
9292 {
9293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9294
9295         reset_async
9296
9297         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9298         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9299         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9300
9301         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9302                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9303                 return 1;
9304         fi
9305         rm -f $DIR/$tfile
9306 }
9307 run_test 118a "verify O_SYNC works =========="
9308
9309 test_118b()
9310 {
9311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9312         remote_ost_nodsh && skip "remote OST with nodsh"
9313
9314         reset_async
9315
9316         #define OBD_FAIL_SRV_ENOENT 0x217
9317         set_nodes_failloc "$(osts_nodes)" 0x217
9318         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9319         RC=$?
9320         set_nodes_failloc "$(osts_nodes)" 0
9321         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9322         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9323                     grep -c writeback)
9324
9325         if [[ $RC -eq 0 ]]; then
9326                 error "Must return error due to dropped pages, rc=$RC"
9327                 return 1;
9328         fi
9329
9330         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9331                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9332                 return 1;
9333         fi
9334
9335         echo "Dirty pages not leaked on ENOENT"
9336
9337         # Due to the above error the OSC will issue all RPCs syncronously
9338         # until a subsequent RPC completes successfully without error.
9339         $MULTIOP $DIR/$tfile Ow4096yc
9340         rm -f $DIR/$tfile
9341
9342         return 0
9343 }
9344 run_test 118b "Reclaim dirty pages on fatal error =========="
9345
9346 test_118c()
9347 {
9348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9349
9350         # for 118c, restore the original resend count, LU-1940
9351         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
9352                                 set_resend_count $OLD_RESENDCOUNT
9353         remote_ost_nodsh && skip "remote OST with nodsh"
9354
9355         reset_async
9356
9357         #define OBD_FAIL_OST_EROFS               0x216
9358         set_nodes_failloc "$(osts_nodes)" 0x216
9359
9360         # multiop should block due to fsync until pages are written
9361         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9362         MULTIPID=$!
9363         sleep 1
9364
9365         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9366                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9367         fi
9368
9369         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9370                     grep -c writeback)
9371         if [[ $WRITEBACK -eq 0 ]]; then
9372                 error "No page in writeback, writeback=$WRITEBACK"
9373         fi
9374
9375         set_nodes_failloc "$(osts_nodes)" 0
9376         wait $MULTIPID
9377         RC=$?
9378         if [[ $RC -ne 0 ]]; then
9379                 error "Multiop fsync failed, rc=$RC"
9380         fi
9381
9382         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9383         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9384                     grep -c writeback)
9385         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9386                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9387         fi
9388
9389         rm -f $DIR/$tfile
9390         echo "Dirty pages flushed via fsync on EROFS"
9391         return 0
9392 }
9393 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
9394
9395 # continue to use small resend count to reduce test_118* time (b=14842)
9396 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9397
9398 test_118d()
9399 {
9400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9401         remote_ost_nodsh && skip "remote OST with nodsh"
9402
9403         reset_async
9404
9405         #define OBD_FAIL_OST_BRW_PAUSE_BULK
9406         set_nodes_failloc "$(osts_nodes)" 0x214
9407         # multiop should block due to fsync until pages are written
9408         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9409         MULTIPID=$!
9410         sleep 1
9411
9412         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9413                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9414         fi
9415
9416         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9417                     grep -c writeback)
9418         if [[ $WRITEBACK -eq 0 ]]; then
9419                 error "No page in writeback, writeback=$WRITEBACK"
9420         fi
9421
9422         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
9423         set_nodes_failloc "$(osts_nodes)" 0
9424
9425         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9426         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9427                     grep -c writeback)
9428         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9429                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9430         fi
9431
9432         rm -f $DIR/$tfile
9433         echo "Dirty pages gaurenteed flushed via fsync"
9434         return 0
9435 }
9436 run_test 118d "Fsync validation inject a delay of the bulk =========="
9437
9438 test_118f() {
9439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9440
9441         reset_async
9442
9443         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
9444         lctl set_param fail_loc=0x8000040a
9445
9446         # Should simulate EINVAL error which is fatal
9447         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9448         RC=$?
9449         if [[ $RC -eq 0 ]]; then
9450                 error "Must return error due to dropped pages, rc=$RC"
9451         fi
9452
9453         lctl set_param fail_loc=0x0
9454
9455         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9456         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9457         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9458                     grep -c writeback)
9459         if [[ $LOCKED -ne 0 ]]; then
9460                 error "Locked pages remain in cache, locked=$LOCKED"
9461         fi
9462
9463         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9464                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9465         fi
9466
9467         rm -f $DIR/$tfile
9468         echo "No pages locked after fsync"
9469
9470         reset_async
9471         return 0
9472 }
9473 run_test 118f "Simulate unrecoverable OSC side error =========="
9474
9475 test_118g() {
9476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9477
9478         reset_async
9479
9480         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9481         lctl set_param fail_loc=0x406
9482
9483         # simulate local -ENOMEM
9484         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9485         RC=$?
9486
9487         lctl set_param fail_loc=0
9488         if [[ $RC -eq 0 ]]; then
9489                 error "Must return error due to dropped pages, rc=$RC"
9490         fi
9491
9492         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9493         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9494         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9495                         grep -c writeback)
9496         if [[ $LOCKED -ne 0 ]]; then
9497                 error "Locked pages remain in cache, locked=$LOCKED"
9498         fi
9499
9500         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9501                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9502         fi
9503
9504         rm -f $DIR/$tfile
9505         echo "No pages locked after fsync"
9506
9507         reset_async
9508         return 0
9509 }
9510 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
9511
9512 test_118h() {
9513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9514         remote_ost_nodsh && skip "remote OST with nodsh"
9515
9516         reset_async
9517
9518         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9519         set_nodes_failloc "$(osts_nodes)" 0x20e
9520         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
9521         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9522         RC=$?
9523
9524         set_nodes_failloc "$(osts_nodes)" 0
9525         if [[ $RC -eq 0 ]]; then
9526                 error "Must return error due to dropped pages, rc=$RC"
9527         fi
9528
9529         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9530         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9531         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9532                     grep -c writeback)
9533         if [[ $LOCKED -ne 0 ]]; then
9534                 error "Locked pages remain in cache, locked=$LOCKED"
9535         fi
9536
9537         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9538                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9539         fi
9540
9541         rm -f $DIR/$tfile
9542         echo "No pages locked after fsync"
9543
9544         return 0
9545 }
9546 run_test 118h "Verify timeout in handling recoverables errors  =========="
9547
9548 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
9549
9550 test_118i() {
9551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9552         remote_ost_nodsh && skip "remote OST with nodsh"
9553
9554         reset_async
9555
9556         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9557         set_nodes_failloc "$(osts_nodes)" 0x20e
9558
9559         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
9560         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9561         PID=$!
9562         sleep 5
9563         set_nodes_failloc "$(osts_nodes)" 0
9564
9565         wait $PID
9566         RC=$?
9567         if [[ $RC -ne 0 ]]; then
9568                 error "got error, but should be not, rc=$RC"
9569         fi
9570
9571         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9572         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9573         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9574         if [[ $LOCKED -ne 0 ]]; then
9575                 error "Locked pages remain in cache, locked=$LOCKED"
9576         fi
9577
9578         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9579                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9580         fi
9581
9582         rm -f $DIR/$tfile
9583         echo "No pages locked after fsync"
9584
9585         return 0
9586 }
9587 run_test 118i "Fix error before timeout in recoverable error  =========="
9588
9589 [ "$SLOW" = "no" ] && set_resend_count 4
9590
9591 test_118j() {
9592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9593         remote_ost_nodsh && skip "remote OST with nodsh"
9594
9595         reset_async
9596
9597         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
9598         set_nodes_failloc "$(osts_nodes)" 0x220
9599
9600         # return -EIO from OST
9601         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9602         RC=$?
9603         set_nodes_failloc "$(osts_nodes)" 0x0
9604         if [[ $RC -eq 0 ]]; then
9605                 error "Must return error due to dropped pages, rc=$RC"
9606         fi
9607
9608         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9609         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9610         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9611         if [[ $LOCKED -ne 0 ]]; then
9612                 error "Locked pages remain in cache, locked=$LOCKED"
9613         fi
9614
9615         # in recoverable error on OST we want resend and stay until it finished
9616         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9617                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9618         fi
9619
9620         rm -f $DIR/$tfile
9621         echo "No pages locked after fsync"
9622
9623         return 0
9624 }
9625 run_test 118j "Simulate unrecoverable OST side error =========="
9626
9627 test_118k()
9628 {
9629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9630         remote_ost_nodsh && skip "remote OSTs with nodsh"
9631
9632         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9633         set_nodes_failloc "$(osts_nodes)" 0x20e
9634         test_mkdir $DIR/$tdir
9635
9636         for ((i=0;i<10;i++)); do
9637                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
9638                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
9639                 SLEEPPID=$!
9640                 sleep 0.500s
9641                 kill $SLEEPPID
9642                 wait $SLEEPPID
9643         done
9644
9645         set_nodes_failloc "$(osts_nodes)" 0
9646         rm -rf $DIR/$tdir
9647 }
9648 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
9649
9650 test_118l() # LU-646
9651 {
9652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9653
9654         test_mkdir $DIR/$tdir
9655         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
9656         rm -rf $DIR/$tdir
9657 }
9658 run_test 118l "fsync dir"
9659
9660 test_118m() # LU-3066
9661 {
9662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9663
9664         test_mkdir $DIR/$tdir
9665         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
9666         rm -rf $DIR/$tdir
9667 }
9668 run_test 118m "fdatasync dir ========="
9669
9670 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
9671
9672 test_118n()
9673 {
9674         local begin
9675         local end
9676
9677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9678         remote_ost_nodsh && skip "remote OSTs with nodsh"
9679
9680         # Sleep to avoid a cached response.
9681         #define OBD_STATFS_CACHE_SECONDS 1
9682         sleep 2
9683
9684         # Inject a 10 second delay in the OST_STATFS handler.
9685         #define OBD_FAIL_OST_STATFS_DELAY 0x242
9686         set_nodes_failloc "$(osts_nodes)" 0x242
9687
9688         begin=$SECONDS
9689         stat --file-system $MOUNT > /dev/null
9690         end=$SECONDS
9691
9692         set_nodes_failloc "$(osts_nodes)" 0
9693
9694         if ((end - begin > 20)); then
9695             error "statfs took $((end - begin)) seconds, expected 10"
9696         fi
9697 }
9698 run_test 118n "statfs() sends OST_STATFS requests in parallel"
9699
9700 test_119a() # bug 11737
9701 {
9702         BSIZE=$((512 * 1024))
9703         directio write $DIR/$tfile 0 1 $BSIZE
9704         # We ask to read two blocks, which is more than a file size.
9705         # directio will indicate an error when requested and actual
9706         # sizes aren't equeal (a normal situation in this case) and
9707         # print actual read amount.
9708         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
9709         if [ "$NOB" != "$BSIZE" ]; then
9710                 error "read $NOB bytes instead of $BSIZE"
9711         fi
9712         rm -f $DIR/$tfile
9713 }
9714 run_test 119a "Short directIO read must return actual read amount"
9715
9716 test_119b() # bug 11737
9717 {
9718         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9719
9720         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
9721         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
9722         sync
9723         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
9724                 error "direct read failed"
9725         rm -f $DIR/$tfile
9726 }
9727 run_test 119b "Sparse directIO read must return actual read amount"
9728
9729 test_119c() # bug 13099
9730 {
9731         BSIZE=1048576
9732         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
9733         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
9734         rm -f $DIR/$tfile
9735 }
9736 run_test 119c "Testing for direct read hitting hole"
9737
9738 test_119d() # bug 15950
9739 {
9740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9741
9742         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
9743         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
9744         BSIZE=1048576
9745         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
9746         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
9747         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
9748         lctl set_param fail_loc=0x40d
9749         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
9750         pid_dio=$!
9751         sleep 1
9752         cat $DIR/$tfile > /dev/null &
9753         lctl set_param fail_loc=0
9754         pid_reads=$!
9755         wait $pid_dio
9756         log "the DIO writes have completed, now wait for the reads (should not block very long)"
9757         sleep 2
9758         [ -n "`ps h -p $pid_reads -o comm`" ] && \
9759         error "the read rpcs have not completed in 2s"
9760         rm -f $DIR/$tfile
9761         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
9762 }
9763 run_test 119d "The DIO path should try to send a new rpc once one is completed"
9764
9765 test_120a() {
9766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9767         remote_mds_nodsh && skip "remote MDS with nodsh"
9768         test_mkdir -i0 -c1 $DIR/$tdir
9769         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9770                 skip_env "no early lock cancel on server"
9771
9772         lru_resize_disable mdc
9773         lru_resize_disable osc
9774         cancel_lru_locks mdc
9775         # asynchronous object destroy at MDT could cause bl ast to client
9776         cancel_lru_locks osc
9777
9778         stat $DIR/$tdir > /dev/null
9779         can1=$(do_facet mds1 \
9780                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9781                awk '/ldlm_cancel/ {print $2}')
9782         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9783                awk '/ldlm_bl_callback/ {print $2}')
9784         test_mkdir -i0 -c1 $DIR/$tdir/d1
9785         can2=$(do_facet mds1 \
9786                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9787                awk '/ldlm_cancel/ {print $2}')
9788         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9789                awk '/ldlm_bl_callback/ {print $2}')
9790         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9791         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9792         lru_resize_enable mdc
9793         lru_resize_enable osc
9794 }
9795 run_test 120a "Early Lock Cancel: mkdir test"
9796
9797 test_120b() {
9798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9799         remote_mds_nodsh && skip "remote MDS with nodsh"
9800         test_mkdir $DIR/$tdir
9801         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9802                 skip_env "no early lock cancel on server"
9803
9804         lru_resize_disable mdc
9805         lru_resize_disable osc
9806         cancel_lru_locks mdc
9807         stat $DIR/$tdir > /dev/null
9808         can1=$(do_facet $SINGLEMDS \
9809                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9810                awk '/ldlm_cancel/ {print $2}')
9811         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9812                awk '/ldlm_bl_callback/ {print $2}')
9813         touch $DIR/$tdir/f1
9814         can2=$(do_facet $SINGLEMDS \
9815                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9816                awk '/ldlm_cancel/ {print $2}')
9817         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9818                awk '/ldlm_bl_callback/ {print $2}')
9819         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9820         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9821         lru_resize_enable mdc
9822         lru_resize_enable osc
9823 }
9824 run_test 120b "Early Lock Cancel: create test"
9825
9826 test_120c() {
9827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9828         remote_mds_nodsh && skip "remote MDS with nodsh"
9829         test_mkdir -i0 -c1 $DIR/$tdir
9830         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9831                 skip "no early lock cancel on server"
9832
9833         lru_resize_disable mdc
9834         lru_resize_disable osc
9835         test_mkdir -i0 -c1 $DIR/$tdir/d1
9836         test_mkdir -i0 -c1 $DIR/$tdir/d2
9837         touch $DIR/$tdir/d1/f1
9838         cancel_lru_locks mdc
9839         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
9840         can1=$(do_facet mds1 \
9841                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9842                awk '/ldlm_cancel/ {print $2}')
9843         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9844                awk '/ldlm_bl_callback/ {print $2}')
9845         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
9846         can2=$(do_facet mds1 \
9847                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9848                awk '/ldlm_cancel/ {print $2}')
9849         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9850                awk '/ldlm_bl_callback/ {print $2}')
9851         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9852         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9853         lru_resize_enable mdc
9854         lru_resize_enable osc
9855 }
9856 run_test 120c "Early Lock Cancel: link test"
9857
9858 test_120d() {
9859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9860         remote_mds_nodsh && skip "remote MDS with nodsh"
9861         test_mkdir -i0 -c1 $DIR/$tdir
9862         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9863                 skip_env "no early lock cancel on server"
9864
9865         lru_resize_disable mdc
9866         lru_resize_disable osc
9867         touch $DIR/$tdir
9868         cancel_lru_locks mdc
9869         stat $DIR/$tdir > /dev/null
9870         can1=$(do_facet mds1 \
9871                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9872                awk '/ldlm_cancel/ {print $2}')
9873         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9874                awk '/ldlm_bl_callback/ {print $2}')
9875         chmod a+x $DIR/$tdir
9876         can2=$(do_facet mds1 \
9877                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9878                awk '/ldlm_cancel/ {print $2}')
9879         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9880                awk '/ldlm_bl_callback/ {print $2}')
9881         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9882         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9883         lru_resize_enable mdc
9884         lru_resize_enable osc
9885 }
9886 run_test 120d "Early Lock Cancel: setattr test"
9887
9888 test_120e() {
9889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9890         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9891                 skip_env "no early lock cancel on server"
9892         remote_mds_nodsh && skip "remote MDS with nodsh"
9893
9894         local dlmtrace_set=false
9895
9896         test_mkdir -i0 -c1 $DIR/$tdir
9897         lru_resize_disable mdc
9898         lru_resize_disable osc
9899         ! $LCTL get_param debug | grep -q dlmtrace &&
9900                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
9901         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
9902         cancel_lru_locks mdc
9903         cancel_lru_locks osc
9904         dd if=$DIR/$tdir/f1 of=/dev/null
9905         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
9906         # XXX client can not do early lock cancel of OST lock
9907         # during unlink (LU-4206), so cancel osc lock now.
9908         sleep 2
9909         cancel_lru_locks osc
9910         can1=$(do_facet mds1 \
9911                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9912                awk '/ldlm_cancel/ {print $2}')
9913         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9914                awk '/ldlm_bl_callback/ {print $2}')
9915         unlink $DIR/$tdir/f1
9916         sleep 5
9917         can2=$(do_facet mds1 \
9918                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9919                awk '/ldlm_cancel/ {print $2}')
9920         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9921                awk '/ldlm_bl_callback/ {print $2}')
9922         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
9923                 $LCTL dk $TMP/cancel.debug.txt
9924         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
9925                 $LCTL dk $TMP/blocking.debug.txt
9926         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
9927         lru_resize_enable mdc
9928         lru_resize_enable osc
9929 }
9930 run_test 120e "Early Lock Cancel: unlink test"
9931
9932 test_120f() {
9933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9934         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9935                 skip_env "no early lock cancel on server"
9936         remote_mds_nodsh && skip "remote MDS with nodsh"
9937
9938         test_mkdir -i0 -c1 $DIR/$tdir
9939         lru_resize_disable mdc
9940         lru_resize_disable osc
9941         test_mkdir -i0 -c1 $DIR/$tdir/d1
9942         test_mkdir -i0 -c1 $DIR/$tdir/d2
9943         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
9944         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
9945         cancel_lru_locks mdc
9946         cancel_lru_locks osc
9947         dd if=$DIR/$tdir/d1/f1 of=/dev/null
9948         dd if=$DIR/$tdir/d2/f2 of=/dev/null
9949         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
9950         # XXX client can not do early lock cancel of OST lock
9951         # during rename (LU-4206), so cancel osc lock now.
9952         sleep 2
9953         cancel_lru_locks osc
9954         can1=$(do_facet mds1 \
9955                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9956                awk '/ldlm_cancel/ {print $2}')
9957         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9958                awk '/ldlm_bl_callback/ {print $2}')
9959         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
9960         sleep 5
9961         can2=$(do_facet mds1 \
9962                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9963                awk '/ldlm_cancel/ {print $2}')
9964         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9965                awk '/ldlm_bl_callback/ {print $2}')
9966         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9967         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9968         lru_resize_enable mdc
9969         lru_resize_enable osc
9970 }
9971 run_test 120f "Early Lock Cancel: rename test"
9972
9973 test_120g() {
9974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9975         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9976                 skip_env "no early lock cancel on server"
9977         remote_mds_nodsh && skip "remote MDS with nodsh"
9978
9979         lru_resize_disable mdc
9980         lru_resize_disable osc
9981         count=10000
9982         echo create $count files
9983         test_mkdir $DIR/$tdir
9984         cancel_lru_locks mdc
9985         cancel_lru_locks osc
9986         t0=$(date +%s)
9987
9988         can0=$(do_facet $SINGLEMDS \
9989                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9990                awk '/ldlm_cancel/ {print $2}')
9991         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9992                awk '/ldlm_bl_callback/ {print $2}')
9993         createmany -o $DIR/$tdir/f $count
9994         sync
9995         can1=$(do_facet $SINGLEMDS \
9996                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9997                awk '/ldlm_cancel/ {print $2}')
9998         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9999                awk '/ldlm_bl_callback/ {print $2}')
10000         t1=$(date +%s)
10001         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
10002         echo rm $count files
10003         rm -r $DIR/$tdir
10004         sync
10005         can2=$(do_facet $SINGLEMDS \
10006                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10007                awk '/ldlm_cancel/ {print $2}')
10008         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10009                awk '/ldlm_bl_callback/ {print $2}')
10010         t2=$(date +%s)
10011         echo total: $count removes in $((t2-t1))
10012         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
10013         sleep 2
10014         # wait for commitment of removal
10015         lru_resize_enable mdc
10016         lru_resize_enable osc
10017 }
10018 run_test 120g "Early Lock Cancel: performance test"
10019
10020 test_121() { #bug #10589
10021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10022
10023         rm -rf $DIR/$tfile
10024         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
10025 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
10026         lctl set_param fail_loc=0x310
10027         cancel_lru_locks osc > /dev/null
10028         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
10029         lctl set_param fail_loc=0
10030         [[ $reads -eq $writes ]] ||
10031                 error "read $reads blocks, must be $writes blocks"
10032 }
10033 run_test 121 "read cancel race ========="
10034
10035 test_123a() { # was test 123, statahead(bug 11401)
10036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10037
10038         SLOWOK=0
10039         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
10040                 log "testing UP system. Performance may be lower than expected."
10041                 SLOWOK=1
10042         fi
10043
10044         rm -rf $DIR/$tdir
10045         test_mkdir $DIR/$tdir
10046         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
10047         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
10048         MULT=10
10049         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
10050                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
10051
10052                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10053                 lctl set_param -n llite.*.statahead_max 0
10054                 lctl get_param llite.*.statahead_max
10055                 cancel_lru_locks mdc
10056                 cancel_lru_locks osc
10057                 stime=`date +%s`
10058                 time ls -l $DIR/$tdir | wc -l
10059                 etime=`date +%s`
10060                 delta=$((etime - stime))
10061                 log "ls $i files without statahead: $delta sec"
10062                 lctl set_param llite.*.statahead_max=$max
10063
10064                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10065                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
10066                 cancel_lru_locks mdc
10067                 cancel_lru_locks osc
10068                 stime=`date +%s`
10069                 time ls -l $DIR/$tdir | wc -l
10070                 etime=`date +%s`
10071                 delta_sa=$((etime - stime))
10072                 log "ls $i files with statahead: $delta_sa sec"
10073                 lctl get_param -n llite.*.statahead_stats
10074                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10075
10076                 [[ $swrong -lt $ewrong ]] &&
10077                         log "statahead was stopped, maybe too many locks held!"
10078                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
10079
10080                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10081                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10082                     lctl set_param -n llite.*.statahead_max 0
10083                     lctl get_param llite.*.statahead_max
10084                     cancel_lru_locks mdc
10085                     cancel_lru_locks osc
10086                     stime=`date +%s`
10087                     time ls -l $DIR/$tdir | wc -l
10088                     etime=`date +%s`
10089                     delta=$((etime - stime))
10090                     log "ls $i files again without statahead: $delta sec"
10091                     lctl set_param llite.*.statahead_max=$max
10092                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10093                         if [  $SLOWOK -eq 0 ]; then
10094                                 error "ls $i files is slower with statahead!"
10095                         else
10096                                 log "ls $i files is slower with statahead!"
10097                         fi
10098                         break
10099                     fi
10100                 fi
10101
10102                 [ $delta -gt 20 ] && break
10103                 [ $delta -gt 8 ] && MULT=$((50 / delta))
10104                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
10105         done
10106         log "ls done"
10107
10108         stime=`date +%s`
10109         rm -r $DIR/$tdir
10110         sync
10111         etime=`date +%s`
10112         delta=$((etime - stime))
10113         log "rm -r $DIR/$tdir/: $delta seconds"
10114         log "rm done"
10115         lctl get_param -n llite.*.statahead_stats
10116 }
10117 run_test 123a "verify statahead work"
10118
10119 test_123b () { # statahead(bug 15027)
10120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10121
10122         test_mkdir $DIR/$tdir
10123         createmany -o $DIR/$tdir/$tfile-%d 1000
10124
10125         cancel_lru_locks mdc
10126         cancel_lru_locks osc
10127
10128 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
10129         lctl set_param fail_loc=0x80000803
10130         ls -lR $DIR/$tdir > /dev/null
10131         log "ls done"
10132         lctl set_param fail_loc=0x0
10133         lctl get_param -n llite.*.statahead_stats
10134         rm -r $DIR/$tdir
10135         sync
10136
10137 }
10138 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
10139
10140 test_124a() {
10141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10142         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10143                 skip_env "no lru resize on server"
10144
10145         local NR=2000
10146
10147         test_mkdir $DIR/$tdir
10148
10149         log "create $NR files at $DIR/$tdir"
10150         createmany -o $DIR/$tdir/f $NR ||
10151                 error "failed to create $NR files in $DIR/$tdir"
10152
10153         cancel_lru_locks mdc
10154         ls -l $DIR/$tdir > /dev/null
10155
10156         local NSDIR=""
10157         local LRU_SIZE=0
10158         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
10159                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
10160                 LRU_SIZE=$($LCTL get_param -n $PARAM)
10161                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
10162                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
10163                         log "NSDIR=$NSDIR"
10164                         log "NS=$(basename $NSDIR)"
10165                         break
10166                 fi
10167         done
10168
10169         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
10170                 skip "Not enough cached locks created!"
10171         fi
10172         log "LRU=$LRU_SIZE"
10173
10174         local SLEEP=30
10175
10176         # We know that lru resize allows one client to hold $LIMIT locks
10177         # for 10h. After that locks begin to be killed by client.
10178         local MAX_HRS=10
10179         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
10180         log "LIMIT=$LIMIT"
10181         if [ $LIMIT -lt $LRU_SIZE ]; then
10182                 skip "Limit is too small $LIMIT"
10183         fi
10184
10185         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
10186         # killing locks. Some time was spent for creating locks. This means
10187         # that up to the moment of sleep finish we must have killed some of
10188         # them (10-100 locks). This depends on how fast ther were created.
10189         # Many of them were touched in almost the same moment and thus will
10190         # be killed in groups.
10191         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
10192
10193         # Use $LRU_SIZE_B here to take into account real number of locks
10194         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
10195         local LRU_SIZE_B=$LRU_SIZE
10196         log "LVF=$LVF"
10197         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
10198         log "OLD_LVF=$OLD_LVF"
10199         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
10200
10201         # Let's make sure that we really have some margin. Client checks
10202         # cached locks every 10 sec.
10203         SLEEP=$((SLEEP+20))
10204         log "Sleep ${SLEEP} sec"
10205         local SEC=0
10206         while ((SEC<$SLEEP)); do
10207                 echo -n "..."
10208                 sleep 5
10209                 SEC=$((SEC+5))
10210                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
10211                 echo -n "$LRU_SIZE"
10212         done
10213         echo ""
10214         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
10215         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
10216
10217         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
10218                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
10219                 unlinkmany $DIR/$tdir/f $NR
10220                 return
10221         }
10222
10223         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
10224         log "unlink $NR files at $DIR/$tdir"
10225         unlinkmany $DIR/$tdir/f $NR
10226 }
10227 run_test 124a "lru resize ======================================="
10228
10229 get_max_pool_limit()
10230 {
10231         local limit=$($LCTL get_param \
10232                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
10233         local max=0
10234         for l in $limit; do
10235                 if [[ $l -gt $max ]]; then
10236                         max=$l
10237                 fi
10238         done
10239         echo $max
10240 }
10241
10242 test_124b() {
10243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10244         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10245                 skip_env "no lru resize on server"
10246
10247         LIMIT=$(get_max_pool_limit)
10248
10249         NR=$(($(default_lru_size)*20))
10250         if [[ $NR -gt $LIMIT ]]; then
10251                 log "Limit lock number by $LIMIT locks"
10252                 NR=$LIMIT
10253         fi
10254
10255         IFree=$(mdsrate_inodes_available)
10256         if [ $IFree -lt $NR ]; then
10257                 log "Limit lock number by $IFree inodes"
10258                 NR=$IFree
10259         fi
10260
10261         lru_resize_disable mdc
10262         test_mkdir -p $DIR/$tdir/disable_lru_resize
10263
10264         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
10265         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
10266         cancel_lru_locks mdc
10267         stime=`date +%s`
10268         PID=""
10269         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10270         PID="$PID $!"
10271         sleep 2
10272         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10273         PID="$PID $!"
10274         sleep 2
10275         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10276         PID="$PID $!"
10277         wait $PID
10278         etime=`date +%s`
10279         nolruresize_delta=$((etime-stime))
10280         log "ls -la time: $nolruresize_delta seconds"
10281         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10282         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
10283
10284         lru_resize_enable mdc
10285         test_mkdir -p $DIR/$tdir/enable_lru_resize
10286
10287         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
10288         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
10289         cancel_lru_locks mdc
10290         stime=`date +%s`
10291         PID=""
10292         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10293         PID="$PID $!"
10294         sleep 2
10295         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10296         PID="$PID $!"
10297         sleep 2
10298         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10299         PID="$PID $!"
10300         wait $PID
10301         etime=`date +%s`
10302         lruresize_delta=$((etime-stime))
10303         log "ls -la time: $lruresize_delta seconds"
10304         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10305
10306         if [ $lruresize_delta -gt $nolruresize_delta ]; then
10307                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
10308         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
10309                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
10310         else
10311                 log "lru resize performs the same with no lru resize"
10312         fi
10313         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
10314 }
10315 run_test 124b "lru resize (performance test) ======================="
10316
10317 test_124c() {
10318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10319         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10320                 skip_env "no lru resize on server"
10321
10322         # cache ununsed locks on client
10323         local nr=100
10324         cancel_lru_locks mdc
10325         test_mkdir $DIR/$tdir
10326         createmany -o $DIR/$tdir/f $nr ||
10327                 error "failed to create $nr files in $DIR/$tdir"
10328         ls -l $DIR/$tdir > /dev/null
10329
10330         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
10331         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
10332         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
10333         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
10334         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
10335
10336         # set lru_max_age to 1 sec
10337         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
10338         echo "sleep $((recalc_p * 2)) seconds..."
10339         sleep $((recalc_p * 2))
10340
10341         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
10342         # restore lru_max_age
10343         $LCTL set_param -n $nsdir.lru_max_age $max_age
10344         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
10345         unlinkmany $DIR/$tdir/f $nr
10346 }
10347 run_test 124c "LRUR cancel very aged locks"
10348
10349 test_125() { # 13358
10350         $LCTL get_param -n llite.*.client_type | grep -q local ||
10351                 skip "must run as local client"
10352         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
10353                 skip_env "must have acl enabled"
10354         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
10355
10356         test_mkdir $DIR/$tdir
10357         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
10358         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
10359         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
10360 }
10361 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
10362
10363 test_126() { # bug 12829/13455
10364         $GSS && skip_env "must run as gss disabled"
10365         $LCTL get_param -n llite.*.client_type | grep -q local ||
10366                 skip "must run as local client"
10367         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
10368
10369         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
10370         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
10371         rm -f $DIR/$tfile
10372         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
10373 }
10374 run_test 126 "check that the fsgid provided by the client is taken into account"
10375
10376 test_127a() { # bug 15521
10377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10378
10379         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
10380         $LCTL set_param osc.*.stats=0
10381         FSIZE=$((2048 * 1024))
10382         dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
10383         cancel_lru_locks osc
10384         dd if=$DIR/$tfile of=/dev/null bs=$FSIZE
10385
10386         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/${tfile}.tmp
10387         while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
10388                 echo "got $COUNT $NAME"
10389                 [ ! $MIN ] && error "Missing min value for $NAME proc entry"
10390                 eval $NAME=$COUNT || error "Wrong proc format"
10391
10392                 case $NAME in
10393                         read_bytes|write_bytes)
10394                         [ $MIN -lt 4096 ] && error "min is too small: $MIN"
10395                         [ $MIN -gt $FSIZE ] && error "min is too big: $MIN"
10396                         [ $MAX -lt 4096 ] && error "max is too small: $MAX"
10397                         [ $MAX -gt $FSIZE ] && error "max is too big: $MAX"
10398                         [ $SUM -ne $FSIZE ] && error "sum is wrong: $SUM"
10399                         [ $SUMSQ -lt $(((FSIZE /4096) * (4096 * 4096))) ] &&
10400                                 error "sumsquare is too small: $SUMSQ"
10401                         [ $SUMSQ -gt $((FSIZE * FSIZE)) ] &&
10402                                 error "sumsquare is too big: $SUMSQ"
10403                         ;;
10404                         *) ;;
10405                 esac
10406         done < $DIR/${tfile}.tmp
10407
10408         #check that we actually got some stats
10409         [ "$read_bytes" ] || error "Missing read_bytes stats"
10410         [ "$write_bytes" ] || error "Missing write_bytes stats"
10411         [ "$read_bytes" != 0 ] || error "no read done"
10412         [ "$write_bytes" != 0 ] || error "no write done"
10413 }
10414 run_test 127a "verify the client stats are sane"
10415
10416 test_127b() { # bug LU-333
10417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10418         local name count samp unit min max sum sumsq
10419
10420         $LCTL set_param llite.*.stats=0
10421
10422         # perform 2 reads and writes so MAX is different from SUM.
10423         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10424         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10425         cancel_lru_locks osc
10426         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10427         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10428
10429         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
10430         while read name count samp unit min max sum sumsq; do
10431                 echo "got $count $name"
10432                 eval $name=$count || error "Wrong proc format"
10433
10434                 case $name in
10435                 read_bytes)
10436                         [ $count -ne 2 ] && error "count is not 2: $count"
10437                         [ $min -ne $PAGE_SIZE ] &&
10438                                 error "min is not $PAGE_SIZE: $min"
10439                         [ $max -ne $PAGE_SIZE ] &&
10440                                 error "max is incorrect: $max"
10441                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10442                                 error "sum is wrong: $sum"
10443                         ;;
10444                 write_bytes)
10445                         [ $count -ne 2 ] && error "count is not 2: $count"
10446                         [ $min -ne $PAGE_SIZE ] &&
10447                                 error "min is not $PAGE_SIZE: $min"
10448                         [ $max -ne $PAGE_SIZE ] &&
10449                                 error "max is incorrect: $max"
10450                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10451                                 error "sum is wrong: $sum"
10452                         ;;
10453                 *) ;;
10454                 esac
10455         done < $TMP/$tfile.tmp
10456
10457         #check that we actually got some stats
10458         [ "$read_bytes" ] || error "Missing read_bytes stats"
10459         [ "$write_bytes" ] || error "Missing write_bytes stats"
10460         [ "$read_bytes" != 0 ] || error "no read done"
10461         [ "$write_bytes" != 0 ] || error "no write done"
10462
10463         rm -f $TMP/${tfile}.tmp
10464 }
10465 run_test 127b "verify the llite client stats are sane"
10466
10467 test_128() { # bug 15212
10468         touch $DIR/$tfile
10469         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
10470                 find $DIR/$tfile
10471                 find $DIR/$tfile
10472         EOF
10473
10474         result=$(grep error $TMP/$tfile.log)
10475         rm -f $DIR/$tfile $TMP/$tfile.log
10476         [ -z "$result" ] ||
10477                 error "consecutive find's under interactive lfs failed"
10478 }
10479 run_test 128 "interactive lfs for 2 consecutive find's"
10480
10481 set_dir_limits () {
10482         local mntdev
10483         local canondev
10484         local node
10485
10486         local ldproc=/proc/fs/ldiskfs
10487         local facets=$(get_facets MDS)
10488
10489         for facet in ${facets//,/ }; do
10490                 canondev=$(ldiskfs_canon \
10491                            *.$(convert_facet2label $facet).mntdev $facet)
10492                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
10493                         ldproc=/sys/fs/ldiskfs
10494                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
10495                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
10496         done
10497 }
10498
10499 check_mds_dmesg() {
10500         local facets=$(get_facets MDS)
10501         for facet in ${facets//,/ }; do
10502                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
10503         done
10504         return 1
10505 }
10506
10507 test_129() {
10508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10509         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
10510                 skip "Need MDS version with at least 2.5.56"
10511         if [ "$mds1_FSTYPE" != ldiskfs ]; then
10512                 skip_env "ldiskfs only test"
10513         fi
10514         remote_mds_nodsh && skip "remote MDS with nodsh"
10515
10516         local ENOSPC=28
10517         local EFBIG=27
10518         local has_warning=false
10519
10520         rm -rf $DIR/$tdir
10521         mkdir -p $DIR/$tdir
10522
10523         # block size of mds1
10524         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
10525         set_dir_limits $maxsize $maxsize
10526         local dirsize=$(stat -c%s "$DIR/$tdir")
10527         local nfiles=0
10528         while [[ $dirsize -le $maxsize ]]; do
10529                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
10530                 rc=$?
10531                 if ! $has_warning; then
10532                         check_mds_dmesg '"is approaching"' && has_warning=true
10533                 fi
10534                 # check two errors:
10535                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
10536                 # EFBIG for previous versions included in ldiskfs series
10537                 if [ $rc -eq $EFBIG -o $rc -eq $ENOSPC ]; then
10538                         set_dir_limits 0 0
10539                         echo "return code $rc received as expected"
10540
10541                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
10542                                 error_exit "create failed w/o dir size limit"
10543
10544                         check_mds_dmesg '"has reached"' ||
10545                                 error_exit "reached message should be output"
10546
10547                         [ $has_warning = "false" ] &&
10548                                 error_exit "warning message should be output"
10549
10550                         dirsize=$(stat -c%s "$DIR/$tdir")
10551
10552                         [[ $dirsize -ge $maxsize ]] && return 0
10553                         error_exit "current dir size $dirsize, " \
10554                                    "previous limit $maxsize"
10555                 elif [ $rc -ne 0 ]; then
10556                         set_dir_limits 0 0
10557                         error_exit "return $rc received instead of expected " \
10558                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
10559                 fi
10560                 nfiles=$((nfiles + 1))
10561                 dirsize=$(stat -c%s "$DIR/$tdir")
10562         done
10563
10564         set_dir_limits 0 0
10565         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
10566 }
10567 run_test 129 "test directory size limit ========================"
10568
10569 OLDIFS="$IFS"
10570 cleanup_130() {
10571         trap 0
10572         IFS="$OLDIFS"
10573 }
10574
10575 test_130a() {
10576         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10577         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10578
10579         trap cleanup_130 EXIT RETURN
10580
10581         local fm_file=$DIR/$tfile
10582         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
10583         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
10584                 error "dd failed for $fm_file"
10585
10586         # LU-1795: test filefrag/FIEMAP once, even if unsupported
10587         filefrag -ves $fm_file
10588         RC=$?
10589         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10590                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10591         [ $RC != 0 ] && error "filefrag $fm_file failed"
10592
10593         filefrag_op=$(filefrag -ve -k $fm_file |
10594                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10595         lun=$($LFS getstripe -i $fm_file)
10596
10597         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
10598         IFS=$'\n'
10599         tot_len=0
10600         for line in $filefrag_op
10601         do
10602                 frag_lun=`echo $line | cut -d: -f5`
10603                 ext_len=`echo $line | cut -d: -f4`
10604                 if (( $frag_lun != $lun )); then
10605                         cleanup_130
10606                         error "FIEMAP on 1-stripe file($fm_file) failed"
10607                         return
10608                 fi
10609                 (( tot_len += ext_len ))
10610         done
10611
10612         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
10613                 cleanup_130
10614                 error "FIEMAP on 1-stripe file($fm_file) failed;"
10615                 return
10616         fi
10617
10618         cleanup_130
10619
10620         echo "FIEMAP on single striped file succeeded"
10621 }
10622 run_test 130a "FIEMAP (1-stripe file)"
10623
10624 test_130b() {
10625         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
10626
10627         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10628         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10629
10630         trap cleanup_130 EXIT RETURN
10631
10632         local fm_file=$DIR/$tfile
10633         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
10634                         error "setstripe on $fm_file"
10635         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10636                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10637
10638         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
10639                 error "dd failed on $fm_file"
10640
10641         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10642         filefrag_op=$(filefrag -ve -k $fm_file |
10643                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10644
10645         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10646                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10647
10648         IFS=$'\n'
10649         tot_len=0
10650         num_luns=1
10651         for line in $filefrag_op
10652         do
10653                 frag_lun=$(echo $line | cut -d: -f5 |
10654                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10655                 ext_len=$(echo $line | cut -d: -f4)
10656                 if (( $frag_lun != $last_lun )); then
10657                         if (( tot_len != 1024 )); then
10658                                 cleanup_130
10659                                 error "FIEMAP on $fm_file failed; returned " \
10660                                 "len $tot_len for OST $last_lun instead of 1024"
10661                                 return
10662                         else
10663                                 (( num_luns += 1 ))
10664                                 tot_len=0
10665                         fi
10666                 fi
10667                 (( tot_len += ext_len ))
10668                 last_lun=$frag_lun
10669         done
10670         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
10671                 cleanup_130
10672                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10673                         "luns or wrong len for OST $last_lun"
10674                 return
10675         fi
10676
10677         cleanup_130
10678
10679         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
10680 }
10681 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
10682
10683 test_130c() {
10684         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10685
10686         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10687         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10688
10689         trap cleanup_130 EXIT RETURN
10690
10691         local fm_file=$DIR/$tfile
10692         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
10693         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10694                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10695
10696         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
10697                         error "dd failed on $fm_file"
10698
10699         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10700         filefrag_op=$(filefrag -ve -k $fm_file |
10701                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10702
10703         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10704                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10705
10706         IFS=$'\n'
10707         tot_len=0
10708         num_luns=1
10709         for line in $filefrag_op
10710         do
10711                 frag_lun=$(echo $line | cut -d: -f5 |
10712                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10713                 ext_len=$(echo $line | cut -d: -f4)
10714                 if (( $frag_lun != $last_lun )); then
10715                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
10716                         if (( logical != 512 )); then
10717                                 cleanup_130
10718                                 error "FIEMAP on $fm_file failed; returned " \
10719                                 "logical start for lun $logical instead of 512"
10720                                 return
10721                         fi
10722                         if (( tot_len != 512 )); then
10723                                 cleanup_130
10724                                 error "FIEMAP on $fm_file failed; returned " \
10725                                 "len $tot_len for OST $last_lun instead of 1024"
10726                                 return
10727                         else
10728                                 (( num_luns += 1 ))
10729                                 tot_len=0
10730                         fi
10731                 fi
10732                 (( tot_len += ext_len ))
10733                 last_lun=$frag_lun
10734         done
10735         if (( num_luns != 2 || tot_len != 512 )); then
10736                 cleanup_130
10737                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10738                         "luns or wrong len for OST $last_lun"
10739                 return
10740         fi
10741
10742         cleanup_130
10743
10744         echo "FIEMAP on 2-stripe file with hole succeeded"
10745 }
10746 run_test 130c "FIEMAP (2-stripe file with hole)"
10747
10748 test_130d() {
10749         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
10750
10751         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10752         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10753
10754         trap cleanup_130 EXIT RETURN
10755
10756         local fm_file=$DIR/$tfile
10757         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
10758                         error "setstripe on $fm_file"
10759         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10760                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10761
10762         local actual_stripe_count=$($LFS getstripe -c $fm_file)
10763         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
10764                 error "dd failed on $fm_file"
10765
10766         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10767         filefrag_op=$(filefrag -ve -k $fm_file |
10768                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10769
10770         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10771                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10772
10773         IFS=$'\n'
10774         tot_len=0
10775         num_luns=1
10776         for line in $filefrag_op
10777         do
10778                 frag_lun=$(echo $line | cut -d: -f5 |
10779                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10780                 ext_len=$(echo $line | cut -d: -f4)
10781                 if (( $frag_lun != $last_lun )); then
10782                         if (( tot_len != 1024 )); then
10783                                 cleanup_130
10784                                 error "FIEMAP on $fm_file failed; returned " \
10785                                 "len $tot_len for OST $last_lun instead of 1024"
10786                                 return
10787                         else
10788                                 (( num_luns += 1 ))
10789                                 tot_len=0
10790                         fi
10791                 fi
10792                 (( tot_len += ext_len ))
10793                 last_lun=$frag_lun
10794         done
10795         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
10796                 cleanup_130
10797                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10798                         "luns or wrong len for OST $last_lun"
10799                 return
10800         fi
10801
10802         cleanup_130
10803
10804         echo "FIEMAP on N-stripe file succeeded"
10805 }
10806 run_test 130d "FIEMAP (N-stripe file)"
10807
10808 test_130e() {
10809         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10810
10811         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10812         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10813
10814         trap cleanup_130 EXIT RETURN
10815
10816         local fm_file=$DIR/$tfile
10817         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
10818         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10819                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10820
10821         NUM_BLKS=512
10822         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
10823         for ((i = 0; i < $NUM_BLKS; i++))
10824         do
10825                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
10826         done
10827
10828         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10829         filefrag_op=$(filefrag -ve -k $fm_file |
10830                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10831
10832         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10833                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10834
10835         IFS=$'\n'
10836         tot_len=0
10837         num_luns=1
10838         for line in $filefrag_op
10839         do
10840                 frag_lun=$(echo $line | cut -d: -f5 |
10841                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10842                 ext_len=$(echo $line | cut -d: -f4)
10843                 if (( $frag_lun != $last_lun )); then
10844                         if (( tot_len != $EXPECTED_LEN )); then
10845                                 cleanup_130
10846                                 error "FIEMAP on $fm_file failed; returned " \
10847                                 "len $tot_len for OST $last_lun instead " \
10848                                 "of $EXPECTED_LEN"
10849                                 return
10850                         else
10851                                 (( num_luns += 1 ))
10852                                 tot_len=0
10853                         fi
10854                 fi
10855                 (( tot_len += ext_len ))
10856                 last_lun=$frag_lun
10857         done
10858         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
10859                 cleanup_130
10860                 error "FIEMAP on $fm_file failed; returned wrong number " \
10861                         "of luns or wrong len for OST $last_lun"
10862                 return
10863         fi
10864
10865         cleanup_130
10866
10867         echo "FIEMAP with continuation calls succeeded"
10868 }
10869 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
10870
10871 test_130f() {
10872         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10873         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10874
10875         local fm_file=$DIR/$tfile
10876         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
10877                 error "multiop create with lov_delay_create on $fm_file"
10878
10879         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10880         filefrag_extents=$(filefrag -vek $fm_file |
10881                            awk '/extents? found/ { print $2 }')
10882         if [[ "$filefrag_extents" != "0" ]]; then
10883                 error "FIEMAP on $fm_file failed; " \
10884                       "returned $filefrag_extents expected 0"
10885         fi
10886
10887         rm -f $fm_file
10888 }
10889 run_test 130f "FIEMAP (unstriped file)"
10890
10891 # Test for writev/readv
10892 test_131a() {
10893         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
10894                 error "writev test failed"
10895         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
10896                 error "readv failed"
10897         rm -f $DIR/$tfile
10898 }
10899 run_test 131a "test iov's crossing stripe boundary for writev/readv"
10900
10901 test_131b() {
10902         local fsize=$((524288 + 1048576 + 1572864))
10903         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
10904                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
10905                         error "append writev test failed"
10906
10907         ((fsize += 1572864 + 1048576))
10908         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
10909                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
10910                         error "append writev test failed"
10911         rm -f $DIR/$tfile
10912 }
10913 run_test 131b "test append writev"
10914
10915 test_131c() {
10916         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
10917         error "NOT PASS"
10918 }
10919 run_test 131c "test read/write on file w/o objects"
10920
10921 test_131d() {
10922         rwv -f $DIR/$tfile -w -n 1 1572864
10923         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
10924         if [ "$NOB" != 1572864 ]; then
10925                 error "Short read filed: read $NOB bytes instead of 1572864"
10926         fi
10927         rm -f $DIR/$tfile
10928 }
10929 run_test 131d "test short read"
10930
10931 test_131e() {
10932         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
10933         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
10934         error "read hitting hole failed"
10935         rm -f $DIR/$tfile
10936 }
10937 run_test 131e "test read hitting hole"
10938
10939 check_stats() {
10940         local facet=$1
10941         local op=$2
10942         local want=${3:-0}
10943         local res
10944
10945         case $facet in
10946         mds*) res=$(do_facet $facet \
10947                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
10948                  ;;
10949         ost*) res=$(do_facet $facet \
10950                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
10951                  ;;
10952         *) error "Wrong facet '$facet'" ;;
10953         esac
10954         [ "$res" ] || error "The counter for $op on $facet was not incremented"
10955         # if the argument $3 is zero, it means any stat increment is ok.
10956         if [[ $want -gt 0 ]]; then
10957                 local count=$(echo $res | awk '{ print $2 }')
10958                 [[ $count -ne $want ]] &&
10959                         error "The $op counter on $facet is $count, not $want"
10960         fi
10961 }
10962
10963 test_133a() {
10964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10965         remote_ost_nodsh && skip "remote OST with nodsh"
10966         remote_mds_nodsh && skip "remote MDS with nodsh"
10967         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
10968                 skip_env "MDS doesn't support rename stats"
10969
10970         local testdir=$DIR/${tdir}/stats_testdir
10971
10972         mkdir -p $DIR/${tdir}
10973
10974         # clear stats.
10975         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
10976         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
10977
10978         # verify mdt stats first.
10979         mkdir ${testdir} || error "mkdir failed"
10980         check_stats $SINGLEMDS "mkdir" 1
10981         touch ${testdir}/${tfile} || error "touch failed"
10982         check_stats $SINGLEMDS "open" 1
10983         check_stats $SINGLEMDS "close" 1
10984         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
10985                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
10986                 check_stats $SINGLEMDS "mknod" 2
10987         }
10988         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
10989         check_stats $SINGLEMDS "unlink" 1
10990         rm -f ${testdir}/${tfile} || error "file remove failed"
10991         check_stats $SINGLEMDS "unlink" 2
10992
10993         # remove working dir and check mdt stats again.
10994         rmdir ${testdir} || error "rmdir failed"
10995         check_stats $SINGLEMDS "rmdir" 1
10996
10997         local testdir1=$DIR/${tdir}/stats_testdir1
10998         mkdir -p ${testdir}
10999         mkdir -p ${testdir1}
11000         touch ${testdir1}/test1
11001         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
11002         check_stats $SINGLEMDS "crossdir_rename" 1
11003
11004         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
11005         check_stats $SINGLEMDS "samedir_rename" 1
11006
11007         rm -rf $DIR/${tdir}
11008 }
11009 run_test 133a "Verifying MDT stats ========================================"
11010
11011 test_133b() {
11012         local res
11013
11014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11015         remote_ost_nodsh && skip "remote OST with nodsh"
11016         remote_mds_nodsh && skip "remote MDS with nodsh"
11017
11018         local testdir=$DIR/${tdir}/stats_testdir
11019
11020         mkdir -p ${testdir} || error "mkdir failed"
11021         touch ${testdir}/${tfile} || error "touch failed"
11022         cancel_lru_locks mdc
11023
11024         # clear stats.
11025         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11026         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11027
11028         # extra mdt stats verification.
11029         chmod 444 ${testdir}/${tfile} || error "chmod failed"
11030         check_stats $SINGLEMDS "setattr" 1
11031         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11032         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
11033         then            # LU-1740
11034                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
11035                 check_stats $SINGLEMDS "getattr" 1
11036         fi
11037         rm -rf $DIR/${tdir}
11038
11039         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
11040         # so the check below is not reliable
11041         [ $MDSCOUNT -eq 1 ] || return 0
11042
11043         # Sleep to avoid a cached response.
11044         #define OBD_STATFS_CACHE_SECONDS 1
11045         sleep 2
11046         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11047         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11048         $LFS df || error "lfs failed"
11049         check_stats $SINGLEMDS "statfs" 1
11050
11051         # check aggregated statfs (LU-10018)
11052         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
11053                 return 0
11054         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
11055                 return 0
11056         sleep 2
11057         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11058         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11059         df $DIR
11060         check_stats $SINGLEMDS "statfs" 1
11061
11062         # We want to check that the client didn't send OST_STATFS to
11063         # ost1 but the MDT also uses OST_STATFS for precreate. So some
11064         # extra care is needed here.
11065         if remote_mds; then
11066                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
11067                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
11068
11069                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
11070                 [ "$res" ] && error "OST got STATFS"
11071         fi
11072
11073         return 0
11074 }
11075 run_test 133b "Verifying extra MDT stats =================================="
11076
11077 test_133c() {
11078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11079         remote_ost_nodsh && skip "remote OST with nodsh"
11080         remote_mds_nodsh && skip "remote MDS with nodsh"
11081
11082         local testdir=$DIR/$tdir/stats_testdir
11083
11084         test_mkdir -p $testdir
11085
11086         # verify obdfilter stats.
11087         $LFS setstripe -c 1 -i 0 $testdir/$tfile
11088         sync
11089         cancel_lru_locks osc
11090         wait_delete_completed
11091
11092         # clear stats.
11093         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11094         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11095
11096         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
11097                 error "dd failed"
11098         sync
11099         cancel_lru_locks osc
11100         check_stats ost1 "write" 1
11101
11102         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
11103         check_stats ost1 "read" 1
11104
11105         > $testdir/$tfile || error "truncate failed"
11106         check_stats ost1 "punch" 1
11107
11108         rm -f $testdir/$tfile || error "file remove failed"
11109         wait_delete_completed
11110         check_stats ost1 "destroy" 1
11111
11112         rm -rf $DIR/$tdir
11113 }
11114 run_test 133c "Verifying OST stats ========================================"
11115
11116 order_2() {
11117         local value=$1
11118         local orig=$value
11119         local order=1
11120
11121         while [ $value -ge 2 ]; do
11122                 order=$((order*2))
11123                 value=$((value/2))
11124         done
11125
11126         if [ $orig -gt $order ]; then
11127                 order=$((order*2))
11128         fi
11129         echo $order
11130 }
11131
11132 size_in_KMGT() {
11133     local value=$1
11134     local size=('K' 'M' 'G' 'T');
11135     local i=0
11136     local size_string=$value
11137
11138     while [ $value -ge 1024 ]; do
11139         if [ $i -gt 3 ]; then
11140             #T is the biggest unit we get here, if that is bigger,
11141             #just return XXXT
11142             size_string=${value}T
11143             break
11144         fi
11145         value=$((value >> 10))
11146         if [ $value -lt 1024 ]; then
11147             size_string=${value}${size[$i]}
11148             break
11149         fi
11150         i=$((i + 1))
11151     done
11152
11153     echo $size_string
11154 }
11155
11156 get_rename_size() {
11157         local size=$1
11158         local context=${2:-.}
11159         local sample=$(do_facet $SINGLEMDS $LCTL \
11160                 get_param mdt.$FSNAME-MDT0000.rename_stats |
11161                 grep -A1 $context |
11162                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
11163         echo $sample
11164 }
11165
11166 test_133d() {
11167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11168         remote_ost_nodsh && skip "remote OST with nodsh"
11169         remote_mds_nodsh && skip "remote MDS with nodsh"
11170         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11171                 skip_env "MDS doesn't support rename stats"
11172
11173         local testdir1=$DIR/${tdir}/stats_testdir1
11174         local testdir2=$DIR/${tdir}/stats_testdir2
11175         mkdir -p $DIR/${tdir}
11176
11177         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11178
11179         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
11180         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
11181
11182         createmany -o $testdir1/test 512 || error "createmany failed"
11183
11184         # check samedir rename size
11185         mv ${testdir1}/test0 ${testdir1}/test_0
11186
11187         local testdir1_size=$(ls -l $DIR/${tdir} |
11188                 awk '/stats_testdir1/ {print $5}')
11189         local testdir2_size=$(ls -l $DIR/${tdir} |
11190                 awk '/stats_testdir2/ {print $5}')
11191
11192         testdir1_size=$(order_2 $testdir1_size)
11193         testdir2_size=$(order_2 $testdir2_size)
11194
11195         testdir1_size=$(size_in_KMGT $testdir1_size)
11196         testdir2_size=$(size_in_KMGT $testdir2_size)
11197
11198         echo "source rename dir size: ${testdir1_size}"
11199         echo "target rename dir size: ${testdir2_size}"
11200
11201         local cmd="do_facet $SINGLEMDS $LCTL "
11202         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
11203
11204         eval $cmd || error "$cmd failed"
11205         local samedir=$($cmd | grep 'same_dir')
11206         local same_sample=$(get_rename_size $testdir1_size)
11207         [ -z "$samedir" ] && error "samedir_rename_size count error"
11208         [[ $same_sample -eq 1 ]] ||
11209                 error "samedir_rename_size error $same_sample"
11210         echo "Check same dir rename stats success"
11211
11212         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11213
11214         # check crossdir rename size
11215         mv ${testdir1}/test_0 ${testdir2}/test_0
11216
11217         testdir1_size=$(ls -l $DIR/${tdir} |
11218                 awk '/stats_testdir1/ {print $5}')
11219         testdir2_size=$(ls -l $DIR/${tdir} |
11220                 awk '/stats_testdir2/ {print $5}')
11221
11222         testdir1_size=$(order_2 $testdir1_size)
11223         testdir2_size=$(order_2 $testdir2_size)
11224
11225         testdir1_size=$(size_in_KMGT $testdir1_size)
11226         testdir2_size=$(size_in_KMGT $testdir2_size)
11227
11228         echo "source rename dir size: ${testdir1_size}"
11229         echo "target rename dir size: ${testdir2_size}"
11230
11231         eval $cmd || error "$cmd failed"
11232         local crossdir=$($cmd | grep 'crossdir')
11233         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
11234         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
11235         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
11236         [[ $src_sample -eq 1 ]] ||
11237                 error "crossdir_rename_size error $src_sample"
11238         [[ $tgt_sample -eq 1 ]] ||
11239                 error "crossdir_rename_size error $tgt_sample"
11240         echo "Check cross dir rename stats success"
11241         rm -rf $DIR/${tdir}
11242 }
11243 run_test 133d "Verifying rename_stats ========================================"
11244
11245 test_133e() {
11246         remote_mds_nodsh && skip "remote MDS with nodsh"
11247         remote_ost_nodsh && skip "remote OST with nodsh"
11248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11249
11250         local testdir=$DIR/${tdir}/stats_testdir
11251         local ctr f0 f1 bs=32768 count=42 sum
11252
11253         mkdir -p ${testdir} || error "mkdir failed"
11254
11255         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
11256
11257         for ctr in {write,read}_bytes; do
11258                 sync
11259                 cancel_lru_locks osc
11260
11261                 do_facet ost1 $LCTL set_param -n \
11262                         "obdfilter.*.exports.clear=clear"
11263
11264                 if [ $ctr = write_bytes ]; then
11265                         f0=/dev/zero
11266                         f1=${testdir}/${tfile}
11267                 else
11268                         f0=${testdir}/${tfile}
11269                         f1=/dev/null
11270                 fi
11271
11272                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
11273                         error "dd failed"
11274                 sync
11275                 cancel_lru_locks osc
11276
11277                 sum=$(do_facet ost1 $LCTL get_param \
11278                         "obdfilter.*.exports.*.stats" |
11279                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
11280                                 $1 == ctr { sum += $7 }
11281                                 END { printf("%0.0f", sum) }')
11282
11283                 if ((sum != bs * count)); then
11284                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
11285                 fi
11286         done
11287
11288         rm -rf $DIR/${tdir}
11289 }
11290 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
11291
11292 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
11293
11294 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
11295 # not honor the -ignore_readdir_race option correctly. So we call
11296 # error_ignore() rather than error() in these cases. See LU-11152.
11297 error_133() {
11298         if (find --version; do_facet mds1 find --version) |
11299                 grep -q '\b4\.5\.1[1-4]\b'; then
11300                 error_ignore LU-11152 "$@"
11301         else
11302                 error "$@"
11303         fi
11304 }
11305
11306 test_133f() {
11307         # First without trusting modes.
11308         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
11309         echo "proc_dirs='$proc_dirs'"
11310         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
11311         find $proc_dirs -exec cat '{}' \; &> /dev/null
11312
11313         # Second verifying readability.
11314         $LCTL get_param -R '*' &> /dev/null
11315
11316         # Verifing writability with badarea_io.
11317         find $proc_dirs \
11318                 -ignore_readdir_race \
11319                 -type f \
11320                 -not -name force_lbug \
11321                 -not -name changelog_mask \
11322                 -exec badarea_io '{}' \; ||
11323                         error_133 "find $proc_dirs failed"
11324 }
11325 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
11326
11327 test_133g() {
11328         remote_mds_nodsh && skip "remote MDS with nodsh"
11329         remote_ost_nodsh && skip "remote OST with nodsh"
11330
11331         # eventually, this can also be replaced with "lctl get_param -R",
11332         # but not until that option is always available on the server
11333         local facet
11334         for facet in mds1 ost1; do
11335                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
11336                         skip_noexit "Too old lustre on $facet"
11337                 local facet_proc_dirs=$(do_facet $facet \
11338                                         \\\ls -d $proc_regexp 2>/dev/null)
11339                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11340                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11341                 do_facet $facet find $facet_proc_dirs \
11342                         ! -name req_history \
11343                         -exec cat '{}' \\\; &> /dev/null
11344
11345                 do_facet $facet find $facet_proc_dirs \
11346                         ! -name req_history \
11347                         -type f \
11348                         -exec cat '{}' \\\; &> /dev/null ||
11349                                 error "proc file read failed"
11350
11351                 do_facet $facet find $facet_proc_dirs \
11352                         -ignore_readdir_race \
11353                         -type f \
11354                         -not -name force_lbug \
11355                         -not -name changelog_mask \
11356                         -exec badarea_io '{}' \\\; ||
11357                                 error_133 "$facet find $facet_proc_dirs failed"
11358         done
11359
11360         # remount the FS in case writes/reads /proc break the FS
11361         cleanup || error "failed to unmount"
11362         setup || error "failed to setup"
11363         true
11364 }
11365 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
11366
11367 test_133h() {
11368         remote_mds_nodsh && skip "remote MDS with nodsh"
11369         remote_ost_nodsh && skip "remote OST with nodsh"
11370         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
11371                 skip "Need MDS version at least 2.9.54"
11372
11373         local facet
11374
11375         for facet in client mds1 ost1; do
11376                 local facet_proc_dirs=$(do_facet $facet \
11377                                         \\\ls -d $proc_regexp 2> /dev/null)
11378                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11379                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11380                 # Get the list of files that are missing the terminating newline
11381                 local missing=($(do_facet $facet \
11382                         find ${facet_proc_dirs} -type f \|              \
11383                                 while read F\; do                       \
11384                                         awk -v FS='\v' -v RS='\v\v'     \
11385                                         "'END { if(NR>0 &&              \
11386                                         \\\$NF !~ /.*\\\n\$/)           \
11387                                                 print FILENAME}'"       \
11388                                         '\$F'\;                         \
11389                                 done 2>/dev/null))
11390                 [ ${#missing[*]} -eq 0 ] ||
11391                         error "files do not end with newline: ${missing[*]}"
11392         done
11393 }
11394 run_test 133h "Proc files should end with newlines"
11395
11396 test_134a() {
11397         remote_mds_nodsh && skip "remote MDS with nodsh"
11398         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11399                 skip "Need MDS version at least 2.7.54"
11400
11401         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11402         cancel_lru_locks mdc
11403
11404         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11405         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11406         [ $unused -eq 0 ] || error "$unused locks are not cleared"
11407
11408         local nr=1000
11409         createmany -o $DIR/$tdir/f $nr ||
11410                 error "failed to create $nr files in $DIR/$tdir"
11411         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11412
11413         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
11414         do_facet mds1 $LCTL set_param fail_loc=0x327
11415         do_facet mds1 $LCTL set_param fail_val=500
11416         touch $DIR/$tdir/m
11417
11418         echo "sleep 10 seconds ..."
11419         sleep 10
11420         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
11421
11422         do_facet mds1 $LCTL set_param fail_loc=0
11423         do_facet mds1 $LCTL set_param fail_val=0
11424         [ $lck_cnt -lt $unused ] ||
11425                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
11426
11427         rm $DIR/$tdir/m
11428         unlinkmany $DIR/$tdir/f $nr
11429 }
11430 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
11431
11432 test_134b() {
11433         remote_mds_nodsh && skip "remote MDS with nodsh"
11434         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11435                 skip "Need MDS version at least 2.7.54"
11436
11437         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11438         cancel_lru_locks mdc
11439
11440         local low_wm=$(do_facet mds1 $LCTL get_param -n \
11441                         ldlm.lock_reclaim_threshold_mb)
11442         # disable reclaim temporarily
11443         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
11444
11445         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
11446         do_facet mds1 $LCTL set_param fail_loc=0x328
11447         do_facet mds1 $LCTL set_param fail_val=500
11448
11449         $LCTL set_param debug=+trace
11450
11451         local nr=600
11452         createmany -o $DIR/$tdir/f $nr &
11453         local create_pid=$!
11454
11455         echo "Sleep $TIMEOUT seconds ..."
11456         sleep $TIMEOUT
11457         if ! ps -p $create_pid  > /dev/null 2>&1; then
11458                 do_facet mds1 $LCTL set_param fail_loc=0
11459                 do_facet mds1 $LCTL set_param fail_val=0
11460                 do_facet mds1 $LCTL set_param \
11461                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
11462                 error "createmany finished incorrectly!"
11463         fi
11464         do_facet mds1 $LCTL set_param fail_loc=0
11465         do_facet mds1 $LCTL set_param fail_val=0
11466         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
11467         wait $create_pid || return 1
11468
11469         unlinkmany $DIR/$tdir/f $nr
11470 }
11471 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
11472
11473 test_140() { #bug-17379
11474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11475
11476         test_mkdir $DIR/$tdir
11477         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
11478         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
11479
11480         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
11481         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
11482         local i=0
11483         while i=$((i + 1)); do
11484                 test_mkdir $i
11485                 cd $i || error "Changing to $i"
11486                 ln -s ../stat stat || error "Creating stat symlink"
11487                 # Read the symlink until ELOOP present,
11488                 # not LBUGing the system is considered success,
11489                 # we didn't overrun the stack.
11490                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
11491                 if [ $ret -ne 0 ]; then
11492                         if [ $ret -eq 40 ]; then
11493                                 break  # -ELOOP
11494                         else
11495                                 error "Open stat symlink"
11496                                         return
11497                         fi
11498                 fi
11499         done
11500         i=$((i - 1))
11501         echo "The symlink depth = $i"
11502         [ $i -eq 5 -o $i -eq 7 -o $i -eq 8 -o $i -eq 40 ] ||
11503                                         error "Invalid symlink depth"
11504
11505         # Test recursive symlink
11506         ln -s symlink_self symlink_self
11507         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
11508         echo "open symlink_self returns $ret"
11509         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
11510 }
11511 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
11512
11513 test_150() {
11514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11515
11516         local TF="$TMP/$tfile"
11517
11518         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
11519         cp $TF $DIR/$tfile
11520         cancel_lru_locks $OSC
11521         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
11522         remount_client $MOUNT
11523         df -P $MOUNT
11524         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
11525
11526         $TRUNCATE $TF 6000
11527         $TRUNCATE $DIR/$tfile 6000
11528         cancel_lru_locks $OSC
11529         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
11530
11531         echo "12345" >>$TF
11532         echo "12345" >>$DIR/$tfile
11533         cancel_lru_locks $OSC
11534         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
11535
11536         echo "12345" >>$TF
11537         echo "12345" >>$DIR/$tfile
11538         cancel_lru_locks $OSC
11539         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
11540
11541         rm -f $TF
11542         true
11543 }
11544 run_test 150 "truncate/append tests"
11545
11546 #LU-2902 roc_hit was not able to read all values from lproc
11547 function roc_hit_init() {
11548         local list=$(comma_list $(osts_nodes))
11549         local dir=$DIR/$tdir-check
11550         local file=$dir/$tfile
11551         local BEFORE
11552         local AFTER
11553         local idx
11554
11555         test_mkdir $dir
11556         #use setstripe to do a write to every ost
11557         for i in $(seq 0 $((OSTCOUNT-1))); do
11558                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
11559                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
11560                 idx=$(printf %04x $i)
11561                 BEFORE=$(get_osd_param $list *OST*$idx stats |
11562                         awk '$1 == "cache_access" {sum += $7}
11563                                 END { printf("%0.0f", sum) }')
11564
11565                 cancel_lru_locks osc
11566                 cat $file >/dev/null
11567
11568                 AFTER=$(get_osd_param $list *OST*$idx stats |
11569                         awk '$1 == "cache_access" {sum += $7}
11570                                 END { printf("%0.0f", sum) }')
11571
11572                 echo BEFORE:$BEFORE AFTER:$AFTER
11573                 if ! let "AFTER - BEFORE == 4"; then
11574                         rm -rf $dir
11575                         error "roc_hit is not safe to use"
11576                 fi
11577                 rm $file
11578         done
11579
11580         rm -rf $dir
11581 }
11582
11583 function roc_hit() {
11584         local list=$(comma_list $(osts_nodes))
11585         echo $(get_osd_param $list '' stats |
11586                 awk '$1 == "cache_hit" {sum += $7}
11587                         END { printf("%0.0f", sum) }')
11588 }
11589
11590 function set_cache() {
11591         local on=1
11592
11593         if [ "$2" == "off" ]; then
11594                 on=0;
11595         fi
11596         local list=$(comma_list $(osts_nodes))
11597         set_osd_param $list '' $1_cache_enable $on
11598
11599         cancel_lru_locks osc
11600 }
11601
11602 test_151() {
11603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11604         remote_ost_nodsh && skip "remote OST with nodsh"
11605
11606         local CPAGES=3
11607         local list=$(comma_list $(osts_nodes))
11608
11609         # check whether obdfilter is cache capable at all
11610         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
11611                 skip "not cache-capable obdfilter"
11612         fi
11613
11614         # check cache is enabled on all obdfilters
11615         if get_osd_param $list '' read_cache_enable | grep 0; then
11616                 skip "oss cache is disabled"
11617         fi
11618
11619         set_osd_param $list '' writethrough_cache_enable 1
11620
11621         # check write cache is enabled on all obdfilters
11622         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
11623                 skip "oss write cache is NOT enabled"
11624         fi
11625
11626         roc_hit_init
11627
11628         #define OBD_FAIL_OBD_NO_LRU  0x609
11629         do_nodes $list $LCTL set_param fail_loc=0x609
11630
11631         # pages should be in the case right after write
11632         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
11633                 error "dd failed"
11634
11635         local BEFORE=$(roc_hit)
11636         cancel_lru_locks osc
11637         cat $DIR/$tfile >/dev/null
11638         local AFTER=$(roc_hit)
11639
11640         do_nodes $list $LCTL set_param fail_loc=0
11641
11642         if ! let "AFTER - BEFORE == CPAGES"; then
11643                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
11644         fi
11645
11646         # the following read invalidates the cache
11647         cancel_lru_locks osc
11648         set_osd_param $list '' read_cache_enable 0
11649         cat $DIR/$tfile >/dev/null
11650
11651         # now data shouldn't be found in the cache
11652         BEFORE=$(roc_hit)
11653         cancel_lru_locks osc
11654         cat $DIR/$tfile >/dev/null
11655         AFTER=$(roc_hit)
11656         if let "AFTER - BEFORE != 0"; then
11657                 error "IN CACHE: before: $BEFORE, after: $AFTER"
11658         fi
11659
11660         set_osd_param $list '' read_cache_enable 1
11661         rm -f $DIR/$tfile
11662 }
11663 run_test 151 "test cache on oss and controls ==============================="
11664
11665 test_152() {
11666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11667
11668         local TF="$TMP/$tfile"
11669
11670         # simulate ENOMEM during write
11671 #define OBD_FAIL_OST_NOMEM      0x226
11672         lctl set_param fail_loc=0x80000226
11673         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
11674         cp $TF $DIR/$tfile
11675         sync || error "sync failed"
11676         lctl set_param fail_loc=0
11677
11678         # discard client's cache
11679         cancel_lru_locks osc
11680
11681         # simulate ENOMEM during read
11682         lctl set_param fail_loc=0x80000226
11683         cmp $TF $DIR/$tfile || error "cmp failed"
11684         lctl set_param fail_loc=0
11685
11686         rm -f $TF
11687 }
11688 run_test 152 "test read/write with enomem ============================"
11689
11690 test_153() {
11691         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
11692 }
11693 run_test 153 "test if fdatasync does not crash ======================="
11694
11695 dot_lustre_fid_permission_check() {
11696         local fid=$1
11697         local ffid=$MOUNT/.lustre/fid/$fid
11698         local test_dir=$2
11699
11700         echo "stat fid $fid"
11701         stat $ffid > /dev/null || error "stat $ffid failed."
11702         echo "touch fid $fid"
11703         touch $ffid || error "touch $ffid failed."
11704         echo "write to fid $fid"
11705         cat /etc/hosts > $ffid || error "write $ffid failed."
11706         echo "read fid $fid"
11707         diff /etc/hosts $ffid || error "read $ffid failed."
11708         echo "append write to fid $fid"
11709         cat /etc/hosts >> $ffid || error "append write $ffid failed."
11710         echo "rename fid $fid"
11711         mv $ffid $test_dir/$tfile.1 &&
11712                 error "rename $ffid to $tfile.1 should fail."
11713         touch $test_dir/$tfile.1
11714         mv $test_dir/$tfile.1 $ffid &&
11715                 error "rename $tfile.1 to $ffid should fail."
11716         rm -f $test_dir/$tfile.1
11717         echo "truncate fid $fid"
11718         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
11719         echo "link fid $fid"
11720         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
11721         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
11722                 echo "setfacl fid $fid"
11723                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
11724                 echo "getfacl fid $fid"
11725                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
11726         fi
11727         echo "unlink fid $fid"
11728         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
11729         echo "mknod fid $fid"
11730         mknod $ffid c 1 3 && error "mknod $ffid should fail."
11731
11732         fid=[0xf00000400:0x1:0x0]
11733         ffid=$MOUNT/.lustre/fid/$fid
11734
11735         echo "stat non-exist fid $fid"
11736         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
11737         echo "write to non-exist fid $fid"
11738         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
11739         echo "link new fid $fid"
11740         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
11741
11742         mkdir -p $test_dir/$tdir
11743         touch $test_dir/$tdir/$tfile
11744         fid=$($LFS path2fid $test_dir/$tdir)
11745         rc=$?
11746         [ $rc -ne 0 ] &&
11747                 error "error: could not get fid for $test_dir/$dir/$tfile."
11748
11749         ffid=$MOUNT/.lustre/fid/$fid
11750
11751         echo "ls $fid"
11752         ls $ffid > /dev/null || error "ls $ffid failed."
11753         echo "touch $fid/$tfile.1"
11754         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
11755
11756         echo "touch $MOUNT/.lustre/fid/$tfile"
11757         touch $MOUNT/.lustre/fid/$tfile && \
11758                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
11759
11760         echo "setxattr to $MOUNT/.lustre/fid"
11761         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
11762
11763         echo "listxattr for $MOUNT/.lustre/fid"
11764         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
11765
11766         echo "delxattr from $MOUNT/.lustre/fid"
11767         setfattr -x trusted.name1 $MOUNT/.lustre/fid
11768
11769         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
11770         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
11771                 error "touch invalid fid should fail."
11772
11773         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
11774         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
11775                 error "touch non-normal fid should fail."
11776
11777         echo "rename $tdir to $MOUNT/.lustre/fid"
11778         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
11779                 error "rename to $MOUNT/.lustre/fid should fail."
11780
11781         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
11782         then            # LU-3547
11783                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
11784                 local new_obf_mode=777
11785
11786                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
11787                 chmod $new_obf_mode $DIR/.lustre/fid ||
11788                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
11789
11790                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
11791                 [ $obf_mode -eq $new_obf_mode ] ||
11792                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
11793
11794                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
11795                 chmod $old_obf_mode $DIR/.lustre/fid ||
11796                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
11797         fi
11798
11799         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
11800         fid=$($LFS path2fid $test_dir/$tfile-2)
11801
11802         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
11803         then # LU-5424
11804                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
11805                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
11806                         error "create lov data thru .lustre failed"
11807         fi
11808         echo "cp /etc/passwd $test_dir/$tfile-2"
11809         cp /etc/passwd $test_dir/$tfile-2 ||
11810                 error "copy to $test_dir/$tfile-2 failed."
11811         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
11812         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
11813                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
11814
11815         rm -rf $test_dir/tfile.lnk
11816         rm -rf $test_dir/$tfile-2
11817 }
11818
11819 test_154A() {
11820         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11821                 skip "Need MDS version at least 2.4.1"
11822
11823         local tf=$DIR/$tfile
11824         touch $tf
11825
11826         local fid=$($LFS path2fid $tf)
11827         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
11828
11829         # check that we get the same pathname back
11830         local found=$($LFS fid2path $MOUNT "$fid")
11831         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
11832         [ "$found" == "$tf" ] ||
11833                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
11834 }
11835 run_test 154A "lfs path2fid and fid2path basic checks"
11836
11837 test_154B() {
11838         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11839                 skip "Need MDS version at least 2.4.1"
11840
11841         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
11842         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
11843         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
11844         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
11845
11846         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
11847         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
11848
11849         # check that we get the same pathname
11850         echo "PFID: $PFID, name: $name"
11851         local FOUND=$($LFS fid2path $MOUNT "$PFID")
11852         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
11853         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
11854                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
11855
11856         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
11857 }
11858 run_test 154B "verify the ll_decode_linkea tool"
11859
11860 test_154a() {
11861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11862         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11863         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
11864                 skip "Need MDS version at least 2.2.51"
11865         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11866
11867         cp /etc/hosts $DIR/$tfile
11868
11869         fid=$($LFS path2fid $DIR/$tfile)
11870         rc=$?
11871         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
11872
11873         dot_lustre_fid_permission_check "$fid" $DIR ||
11874                 error "dot lustre permission check $fid failed"
11875
11876         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
11877
11878         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
11879
11880         touch $MOUNT/.lustre/file &&
11881                 error "creation is not allowed under .lustre"
11882
11883         mkdir $MOUNT/.lustre/dir &&
11884                 error "mkdir is not allowed under .lustre"
11885
11886         rm -rf $DIR/$tfile
11887 }
11888 run_test 154a "Open-by-FID"
11889
11890 test_154b() {
11891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11892         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11893         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
11894         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
11895                 skip "Need MDS version at least 2.2.51"
11896
11897         local remote_dir=$DIR/$tdir/remote_dir
11898         local MDTIDX=1
11899         local rc=0
11900
11901         mkdir -p $DIR/$tdir
11902         $LFS mkdir -i $MDTIDX $remote_dir ||
11903                 error "create remote directory failed"
11904
11905         cp /etc/hosts $remote_dir/$tfile
11906
11907         fid=$($LFS path2fid $remote_dir/$tfile)
11908         rc=$?
11909         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
11910
11911         dot_lustre_fid_permission_check "$fid" $remote_dir ||
11912                 error "dot lustre permission check $fid failed"
11913         rm -rf $DIR/$tdir
11914 }
11915 run_test 154b "Open-by-FID for remote directory"
11916
11917 test_154c() {
11918         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11919                 skip "Need MDS version at least 2.4.1"
11920
11921         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
11922         local FID1=$($LFS path2fid $DIR/$tfile.1)
11923         local FID2=$($LFS path2fid $DIR/$tfile.2)
11924         local FID3=$($LFS path2fid $DIR/$tfile.3)
11925
11926         local N=1
11927         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
11928                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
11929                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
11930                 local want=FID$N
11931                 [ "$FID" = "${!want}" ] ||
11932                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
11933                 N=$((N + 1))
11934         done
11935
11936         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
11937         do
11938                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
11939                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
11940                 N=$((N + 1))
11941         done
11942 }
11943 run_test 154c "lfs path2fid and fid2path multiple arguments"
11944
11945 test_154d() {
11946         remote_mds_nodsh && skip "remote MDS with nodsh"
11947         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
11948                 skip "Need MDS version at least 2.5.53"
11949
11950         if remote_mds; then
11951                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
11952         else
11953                 nid="0@lo"
11954         fi
11955         local proc_ofile="mdt.*.exports.'$nid'.open_files"
11956         local fd
11957         local cmd
11958
11959         rm -f $DIR/$tfile
11960         touch $DIR/$tfile
11961
11962         local fid=$($LFS path2fid $DIR/$tfile)
11963         # Open the file
11964         fd=$(free_fd)
11965         cmd="exec $fd<$DIR/$tfile"
11966         eval $cmd
11967         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
11968         echo "$fid_list" | grep "$fid"
11969         rc=$?
11970
11971         cmd="exec $fd>/dev/null"
11972         eval $cmd
11973         if [ $rc -ne 0 ]; then
11974                 error "FID $fid not found in open files list $fid_list"
11975         fi
11976 }
11977 run_test 154d "Verify open file fid"
11978
11979 test_154e()
11980 {
11981         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
11982                 skip "Need MDS version at least 2.6.50"
11983
11984         if ls -a $MOUNT | grep -q '^\.lustre$'; then
11985                 error ".lustre returned by readdir"
11986         fi
11987 }
11988 run_test 154e ".lustre is not returned by readdir"
11989
11990 test_154f() {
11991         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11992
11993         # create parent directory on a single MDT to avoid cross-MDT hardlinks
11994         test_mkdir -p -c1 $DIR/$tdir/d
11995         # test dirs inherit from its stripe
11996         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
11997         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
11998         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
11999         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
12000         touch $DIR/f
12001
12002         # get fid of parents
12003         local FID0=$($LFS path2fid $DIR/$tdir/d)
12004         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
12005         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
12006         local FID3=$($LFS path2fid $DIR)
12007
12008         # check that path2fid --parents returns expected <parent_fid>/name
12009         # 1) test for a directory (single parent)
12010         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
12011         [ "$parent" == "$FID0/foo1" ] ||
12012                 error "expected parent: $FID0/foo1, got: $parent"
12013
12014         # 2) test for a file with nlink > 1 (multiple parents)
12015         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
12016         echo "$parent" | grep -F "$FID1/$tfile" ||
12017                 error "$FID1/$tfile not returned in parent list"
12018         echo "$parent" | grep -F "$FID2/link" ||
12019                 error "$FID2/link not returned in parent list"
12020
12021         # 3) get parent by fid
12022         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
12023         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12024         echo "$parent" | grep -F "$FID1/$tfile" ||
12025                 error "$FID1/$tfile not returned in parent list (by fid)"
12026         echo "$parent" | grep -F "$FID2/link" ||
12027                 error "$FID2/link not returned in parent list (by fid)"
12028
12029         # 4) test for entry in root directory
12030         parent=$($LFS path2fid --parents $DIR/f)
12031         echo "$parent" | grep -F "$FID3/f" ||
12032                 error "$FID3/f not returned in parent list"
12033
12034         # 5) test it on root directory
12035         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
12036                 error "$MOUNT should not have parents"
12037
12038         # enable xattr caching and check that linkea is correctly updated
12039         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12040         save_lustre_params client "llite.*.xattr_cache" > $save
12041         lctl set_param llite.*.xattr_cache 1
12042
12043         # 6.1) linkea update on rename
12044         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
12045
12046         # get parents by fid
12047         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12048         # foo1 should no longer be returned in parent list
12049         echo "$parent" | grep -F "$FID1" &&
12050                 error "$FID1 should no longer be in parent list"
12051         # the new path should appear
12052         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
12053                 error "$FID2/$tfile.moved is not in parent list"
12054
12055         # 6.2) linkea update on unlink
12056         rm -f $DIR/$tdir/d/foo2/link
12057         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12058         # foo2/link should no longer be returned in parent list
12059         echo "$parent" | grep -F "$FID2/link" &&
12060                 error "$FID2/link should no longer be in parent list"
12061         true
12062
12063         rm -f $DIR/f
12064         restore_lustre_params < $save
12065         rm -f $save
12066 }
12067 run_test 154f "get parent fids by reading link ea"
12068
12069 test_154g()
12070 {
12071         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12072         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
12073            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
12074                 skip "Need MDS version at least 2.6.92"
12075
12076         mkdir -p $DIR/$tdir
12077         llapi_fid_test -d $DIR/$tdir
12078 }
12079 run_test 154g "various llapi FID tests"
12080
12081 test_155_small_load() {
12082     local temp=$TMP/$tfile
12083     local file=$DIR/$tfile
12084
12085     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
12086         error "dd of=$temp bs=6096 count=1 failed"
12087     cp $temp $file
12088     cancel_lru_locks $OSC
12089     cmp $temp $file || error "$temp $file differ"
12090
12091     $TRUNCATE $temp 6000
12092     $TRUNCATE $file 6000
12093     cmp $temp $file || error "$temp $file differ (truncate1)"
12094
12095     echo "12345" >>$temp
12096     echo "12345" >>$file
12097     cmp $temp $file || error "$temp $file differ (append1)"
12098
12099     echo "12345" >>$temp
12100     echo "12345" >>$file
12101     cmp $temp $file || error "$temp $file differ (append2)"
12102
12103     rm -f $temp $file
12104     true
12105 }
12106
12107 test_155_big_load() {
12108         remote_ost_nodsh && skip "remote OST with nodsh"
12109
12110         local temp=$TMP/$tfile
12111         local file=$DIR/$tfile
12112
12113         free_min_max
12114         local cache_size=$(do_facet ost$((MAXI+1)) \
12115                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
12116         local large_file_size=$((cache_size * 2))
12117
12118         echo "OSS cache size: $cache_size KB"
12119         echo "Large file size: $large_file_size KB"
12120
12121         [ $MAXV -le $large_file_size ] &&
12122                 skip_env "max available OST size needs > $large_file_size KB"
12123
12124         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
12125
12126         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
12127                 error "dd of=$temp bs=$large_file_size count=1k failed"
12128         cp $temp $file
12129         ls -lh $temp $file
12130         cancel_lru_locks osc
12131         cmp $temp $file || error "$temp $file differ"
12132
12133         rm -f $temp $file
12134         true
12135 }
12136
12137 save_writethrough() {
12138         local facets=$(get_facets OST)
12139
12140         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
12141 }
12142
12143 test_155a() {
12144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12145
12146         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12147
12148         save_writethrough $p
12149
12150         set_cache read on
12151         set_cache writethrough on
12152         test_155_small_load
12153         restore_lustre_params < $p
12154         rm -f $p
12155 }
12156 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
12157
12158 test_155b() {
12159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12160
12161         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12162
12163         save_writethrough $p
12164
12165         set_cache read on
12166         set_cache writethrough off
12167         test_155_small_load
12168         restore_lustre_params < $p
12169         rm -f $p
12170 }
12171 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
12172
12173 test_155c() {
12174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12175
12176         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12177
12178         save_writethrough $p
12179
12180         set_cache read off
12181         set_cache writethrough on
12182         test_155_small_load
12183         restore_lustre_params < $p
12184         rm -f $p
12185 }
12186 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
12187
12188 test_155d() {
12189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12190
12191         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12192
12193         save_writethrough $p
12194
12195         set_cache read off
12196         set_cache writethrough off
12197         test_155_small_load
12198         restore_lustre_params < $p
12199         rm -f $p
12200 }
12201 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
12202
12203 test_155e() {
12204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12205
12206         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12207
12208         save_writethrough $p
12209
12210         set_cache read on
12211         set_cache writethrough on
12212         test_155_big_load
12213         restore_lustre_params < $p
12214         rm -f $p
12215 }
12216 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
12217
12218 test_155f() {
12219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12220
12221         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12222
12223         save_writethrough $p
12224
12225         set_cache read on
12226         set_cache writethrough off
12227         test_155_big_load
12228         restore_lustre_params < $p
12229         rm -f $p
12230 }
12231 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
12232
12233 test_155g() {
12234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12235
12236         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12237
12238         save_writethrough $p
12239
12240         set_cache read off
12241         set_cache writethrough on
12242         test_155_big_load
12243         restore_lustre_params < $p
12244         rm -f $p
12245 }
12246 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
12247
12248 test_155h() {
12249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12250
12251         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12252
12253         save_writethrough $p
12254
12255         set_cache read off
12256         set_cache writethrough off
12257         test_155_big_load
12258         restore_lustre_params < $p
12259         rm -f $p
12260 }
12261 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
12262
12263 test_156() {
12264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12265         remote_ost_nodsh && skip "remote OST with nodsh"
12266         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
12267                 skip "stats not implemented on old servers"
12268         [ "$ost1_FSTYPE" = "zfs" ] &&
12269                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
12270
12271         local CPAGES=3
12272         local BEFORE
12273         local AFTER
12274         local file="$DIR/$tfile"
12275         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12276
12277         save_writethrough $p
12278         roc_hit_init
12279
12280         log "Turn on read and write cache"
12281         set_cache read on
12282         set_cache writethrough on
12283
12284         log "Write data and read it back."
12285         log "Read should be satisfied from the cache."
12286         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12287         BEFORE=$(roc_hit)
12288         cancel_lru_locks osc
12289         cat $file >/dev/null
12290         AFTER=$(roc_hit)
12291         if ! let "AFTER - BEFORE == CPAGES"; then
12292                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12293         else
12294                 log "cache hits:: before: $BEFORE, after: $AFTER"
12295         fi
12296
12297         log "Read again; it should be satisfied from the cache."
12298         BEFORE=$AFTER
12299         cancel_lru_locks osc
12300         cat $file >/dev/null
12301         AFTER=$(roc_hit)
12302         if ! let "AFTER - BEFORE == CPAGES"; then
12303                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12304         else
12305                 log "cache hits:: before: $BEFORE, after: $AFTER"
12306         fi
12307
12308         log "Turn off the read cache and turn on the write cache"
12309         set_cache read off
12310         set_cache writethrough on
12311
12312         log "Read again; it should be satisfied from the cache."
12313         BEFORE=$(roc_hit)
12314         cancel_lru_locks osc
12315         cat $file >/dev/null
12316         AFTER=$(roc_hit)
12317         if ! let "AFTER - BEFORE == CPAGES"; then
12318                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12319         else
12320                 log "cache hits:: before: $BEFORE, after: $AFTER"
12321         fi
12322
12323         log "Read again; it should not be satisfied from the cache."
12324         BEFORE=$AFTER
12325         cancel_lru_locks osc
12326         cat $file >/dev/null
12327         AFTER=$(roc_hit)
12328         if ! let "AFTER - BEFORE == 0"; then
12329                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12330         else
12331                 log "cache hits:: before: $BEFORE, after: $AFTER"
12332         fi
12333
12334         log "Write data and read it back."
12335         log "Read should be satisfied from the cache."
12336         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12337         BEFORE=$(roc_hit)
12338         cancel_lru_locks osc
12339         cat $file >/dev/null
12340         AFTER=$(roc_hit)
12341         if ! let "AFTER - BEFORE == CPAGES"; then
12342                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12343         else
12344                 log "cache hits:: before: $BEFORE, after: $AFTER"
12345         fi
12346
12347         log "Read again; it should not be satisfied from the cache."
12348         BEFORE=$AFTER
12349         cancel_lru_locks osc
12350         cat $file >/dev/null
12351         AFTER=$(roc_hit)
12352         if ! let "AFTER - BEFORE == 0"; then
12353                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12354         else
12355                 log "cache hits:: before: $BEFORE, after: $AFTER"
12356         fi
12357
12358         log "Turn off read and write cache"
12359         set_cache read off
12360         set_cache writethrough off
12361
12362         log "Write data and read it back"
12363         log "It should not be satisfied from the cache."
12364         rm -f $file
12365         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12366         cancel_lru_locks osc
12367         BEFORE=$(roc_hit)
12368         cat $file >/dev/null
12369         AFTER=$(roc_hit)
12370         if ! let "AFTER - BEFORE == 0"; then
12371                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12372         else
12373                 log "cache hits:: before: $BEFORE, after: $AFTER"
12374         fi
12375
12376         log "Turn on the read cache and turn off the write cache"
12377         set_cache read on
12378         set_cache writethrough off
12379
12380         log "Write data and read it back"
12381         log "It should not be satisfied from the cache."
12382         rm -f $file
12383         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12384         BEFORE=$(roc_hit)
12385         cancel_lru_locks osc
12386         cat $file >/dev/null
12387         AFTER=$(roc_hit)
12388         if ! let "AFTER - BEFORE == 0"; then
12389                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12390         else
12391                 log "cache hits:: before: $BEFORE, after: $AFTER"
12392         fi
12393
12394         log "Read again; it should be satisfied from the cache."
12395         BEFORE=$(roc_hit)
12396         cancel_lru_locks osc
12397         cat $file >/dev/null
12398         AFTER=$(roc_hit)
12399         if ! let "AFTER - BEFORE == CPAGES"; then
12400                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12401         else
12402                 log "cache hits:: before: $BEFORE, after: $AFTER"
12403         fi
12404
12405         restore_lustre_params < $p
12406         rm -f $p $file
12407 }
12408 run_test 156 "Verification of tunables"
12409
12410 test_160a() {
12411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12412         remote_mds_nodsh && skip "remote MDS with nodsh"
12413         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12414                 skip "Need MDS version at least 2.2.0"
12415
12416         changelog_register || error "changelog_register failed"
12417         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12418         changelog_users $SINGLEMDS | grep -q $cl_user ||
12419                 error "User $cl_user not found in changelog_users"
12420
12421         # change something
12422         test_mkdir -p $DIR/$tdir/pics/2008/zachy
12423         changelog_clear 0 || error "changelog_clear failed"
12424         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
12425         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
12426         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
12427         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
12428         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
12429         rm $DIR/$tdir/pics/desktop.jpg
12430
12431         changelog_dump | tail -10
12432
12433         echo "verifying changelog mask"
12434         changelog_chmask "-MKDIR"
12435         changelog_chmask "-CLOSE"
12436
12437         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
12438         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
12439
12440         changelog_chmask "+MKDIR"
12441         changelog_chmask "+CLOSE"
12442
12443         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
12444         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
12445
12446         changelog_dump | tail -10
12447         MKDIRS=$(changelog_dump | grep -c "MKDIR")
12448         CLOSES=$(changelog_dump | grep -c "CLOSE")
12449         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
12450         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
12451
12452         # verify contents
12453         echo "verifying target fid"
12454         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
12455         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
12456         [ "$fidc" == "$fidf" ] ||
12457                 error "changelog '$tfile' fid $fidc != file fid $fidf"
12458         echo "verifying parent fid"
12459         # The FID returned from the Changelog may be the directory shard on
12460         # a different MDT, and not the FID returned by path2fid on the parent.
12461         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
12462         # since this is what will matter when recreating this file in the tree.
12463         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
12464         local pathp=$($LFS fid2path $MOUNT "$fidp")
12465         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
12466                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
12467
12468         echo "getting records for $cl_user"
12469         changelog_users $SINGLEMDS
12470         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
12471         local nclr=3
12472         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
12473                 error "changelog_clear failed"
12474         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
12475         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
12476         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
12477                 error "user index expect $user_rec1 + $nclr != $user_rec2"
12478
12479         local min0_rec=$(changelog_users $SINGLEMDS |
12480                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
12481         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
12482                           awk '{ print $1; exit; }')
12483
12484         changelog_dump | tail -n 5
12485         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
12486         [ $first_rec == $((min0_rec + 1)) ] ||
12487                 error "first index should be $min0_rec + 1 not $first_rec"
12488
12489         # LU-3446 changelog index reset on MDT restart
12490         local cur_rec1=$(changelog_users $SINGLEMDS |
12491                          awk '/^current.index:/ { print $NF }')
12492         changelog_clear 0 ||
12493                 error "clear all changelog records for $cl_user failed"
12494         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
12495         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
12496                 error "Fail to start $SINGLEMDS"
12497         local cur_rec2=$(changelog_users $SINGLEMDS |
12498                          awk '/^current.index:/ { print $NF }')
12499         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
12500         [ $cur_rec1 == $cur_rec2 ] ||
12501                 error "current index should be $cur_rec1 not $cur_rec2"
12502
12503         echo "verifying users from this test are deregistered"
12504         changelog_deregister || error "changelog_deregister failed"
12505         changelog_users $SINGLEMDS | grep -q $cl_user &&
12506                 error "User '$cl_user' still in changelog_users"
12507
12508         # lctl get_param -n mdd.*.changelog_users
12509         # current index: 144
12510         # ID    index (idle seconds)
12511         # cl3   144 (2)
12512         if ! changelog_users $SINGLEMDS | grep "^cl"; then
12513                 # this is the normal case where all users were deregistered
12514                 # make sure no new records are added when no users are present
12515                 local last_rec1=$(changelog_users $SINGLEMDS |
12516                                   awk '/^current.index:/ { print $NF }')
12517                 touch $DIR/$tdir/chloe
12518                 local last_rec2=$(changelog_users $SINGLEMDS |
12519                                   awk '/^current.index:/ { print $NF }')
12520                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
12521                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
12522         else
12523                 # any changelog users must be leftovers from a previous test
12524                 changelog_users $SINGLEMDS
12525                 echo "other changelog users; can't verify off"
12526         fi
12527 }
12528 run_test 160a "changelog sanity"
12529
12530 test_160b() { # LU-3587
12531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12532         remote_mds_nodsh && skip "remote MDS with nodsh"
12533         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12534                 skip "Need MDS version at least 2.2.0"
12535
12536         changelog_register || error "changelog_register failed"
12537         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12538         changelog_users $SINGLEMDS | grep -q $cl_user ||
12539                 error "User '$cl_user' not found in changelog_users"
12540
12541         local longname1=$(str_repeat a 255)
12542         local longname2=$(str_repeat b 255)
12543
12544         cd $DIR
12545         echo "creating very long named file"
12546         touch $longname1 || error "create of '$longname1' failed"
12547         echo "renaming very long named file"
12548         mv $longname1 $longname2
12549
12550         changelog_dump | grep RENME | tail -n 5
12551         rm -f $longname2
12552 }
12553 run_test 160b "Verify that very long rename doesn't crash in changelog"
12554
12555 test_160c() {
12556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12557         remote_mds_nodsh && skip "remote MDS with nodsh"
12558
12559         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
12560                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
12561                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
12562                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
12563
12564         local rc=0
12565
12566         # Registration step
12567         changelog_register || error "changelog_register failed"
12568
12569         rm -rf $DIR/$tdir
12570         mkdir -p $DIR/$tdir
12571         $MCREATE $DIR/$tdir/foo_160c
12572         changelog_chmask "-TRUNC"
12573         $TRUNCATE $DIR/$tdir/foo_160c 200
12574         changelog_chmask "+TRUNC"
12575         $TRUNCATE $DIR/$tdir/foo_160c 199
12576         changelog_dump | tail -n 5
12577         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
12578         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
12579 }
12580 run_test 160c "verify that changelog log catch the truncate event"
12581
12582 test_160d() {
12583         remote_mds_nodsh && skip "remote MDS with nodsh"
12584         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
12585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12586         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
12587                 skip "Need MDS version at least 2.7.60"
12588
12589         # Registration step
12590         changelog_register || error "changelog_register failed"
12591
12592         mkdir -p $DIR/$tdir/migrate_dir
12593         changelog_clear 0 || error "changelog_clear failed"
12594
12595         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
12596         changelog_dump | tail -n 5
12597         local migrates=$(changelog_dump | grep -c "MIGRT")
12598         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
12599 }
12600 run_test 160d "verify that changelog log catch the migrate event"
12601
12602 test_160e() {
12603         remote_mds_nodsh && skip "remote MDS with nodsh"
12604
12605         # Create a user
12606         changelog_register || error "changelog_register failed"
12607
12608         # Delete a future user (expect fail)
12609         local MDT0=$(facet_svc $SINGLEMDS)
12610         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
12611         local rc=$?
12612
12613         if [ $rc -eq 0 ]; then
12614                 error "Deleted non-existant user cl77"
12615         elif [ $rc -ne 2 ]; then
12616                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
12617         fi
12618
12619         # Clear to a bad index (1 billion should be safe)
12620         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
12621         rc=$?
12622
12623         if [ $rc -eq 0 ]; then
12624                 error "Successfully cleared to invalid CL index"
12625         elif [ $rc -ne 22 ]; then
12626                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
12627         fi
12628 }
12629 run_test 160e "changelog negative testing (should return errors)"
12630
12631 test_160f() {
12632         remote_mds_nodsh && skip "remote MDS with nodsh" && return
12633         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12634                 skip "Need MDS version at least 2.10.56"
12635
12636         local mdts=$(comma_list $(mdts_nodes))
12637
12638         # Create a user
12639         changelog_register || error "first changelog_register failed"
12640         changelog_register || error "second changelog_register failed"
12641         local cl_users
12642         declare -A cl_user1
12643         declare -A cl_user2
12644         local user_rec1
12645         local user_rec2
12646         local i
12647
12648         # generate some changelog records to accumulate on each MDT
12649         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
12650         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12651                 error "create $DIR/$tdir/$tfile failed"
12652
12653         # check changelogs have been generated
12654         local nbcl=$(changelog_dump | wc -l)
12655         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12656
12657         for param in "changelog_max_idle_time=10" \
12658                      "changelog_gc=1" \
12659                      "changelog_min_gc_interval=2" \
12660                      "changelog_min_free_cat_entries=3"; do
12661                 local MDT0=$(facet_svc $SINGLEMDS)
12662                 local var="${param%=*}"
12663                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12664
12665                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12666                 do_nodes $mdts $LCTL set_param mdd.*.$param
12667         done
12668
12669         # force cl_user2 to be idle (1st part)
12670         sleep 9
12671
12672         # simulate changelog catalog almost full
12673         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
12674         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
12675
12676         for i in $(seq $MDSCOUNT); do
12677                 cl_users=(${CL_USERS[mds$i]})
12678                 cl_user1[mds$i]="${cl_users[0]}"
12679                 cl_user2[mds$i]="${cl_users[1]}"
12680
12681                 [ -n "${cl_user1[mds$i]}" ] ||
12682                         error "mds$i: no user registered"
12683                 [ -n "${cl_user2[mds$i]}" ] ||
12684                         error "mds$i: only ${cl_user2[mds$i]} is registered"
12685
12686                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12687                 [ -n "$user_rec1" ] ||
12688                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12689                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12690                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12691                 [ -n "$user_rec2" ] ||
12692                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12693                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12694                      "$user_rec1 + 2 == $user_rec2"
12695                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12696                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12697                               "$user_rec1 + 2, but is $user_rec2"
12698                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12699                 [ -n "$user_rec2" ] ||
12700                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12701                 [ $user_rec1 == $user_rec2 ] ||
12702                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12703                               "$user_rec1, but is $user_rec2"
12704         done
12705
12706         # force cl_user2 to be idle (2nd part) and to reach
12707         # changelog_max_idle_time
12708         sleep 2
12709
12710         # generate one more changelog to trigger fail_loc
12711         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12712                 error "create $DIR/$tdir/${tfile}bis failed"
12713
12714         # ensure gc thread is done
12715         for i in $(mdts_nodes); do
12716                 wait_update $i \
12717                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
12718                         error "$i: GC-thread not done"
12719         done
12720
12721         local first_rec
12722         for i in $(seq $MDSCOUNT); do
12723                 # check cl_user1 still registered
12724                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
12725                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12726                 # check cl_user2 unregistered
12727                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
12728                         error "mds$i: User ${cl_user2[mds$i]} still registered"
12729
12730                 # check changelogs are present and starting at $user_rec1 + 1
12731                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12732                 [ -n "$user_rec1" ] ||
12733                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12734                 first_rec=$($LFS changelog $(facet_svc mds$i) |
12735                             awk '{ print $1; exit; }')
12736
12737                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
12738                 [ $((user_rec1 + 1)) == $first_rec ] ||
12739                         error "mds$i: first index should be $user_rec1 + 1, " \
12740                               "but is $first_rec"
12741         done
12742 }
12743 run_test 160f "changelog garbage collect (timestamped users)"
12744
12745 test_160g() {
12746         remote_mds_nodsh && skip "remote MDS with nodsh"
12747         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12748                 skip "Need MDS version at least 2.10.56"
12749
12750         local mdts=$(comma_list $(mdts_nodes))
12751
12752         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
12753         do_nodes $mdts $LCTL set_param fail_loc=0x1314
12754
12755         # Create a user
12756         changelog_register || error "first changelog_register failed"
12757         changelog_register || error "second changelog_register failed"
12758         local cl_users
12759         declare -A cl_user1
12760         declare -A cl_user2
12761         local user_rec1
12762         local user_rec2
12763         local i
12764
12765         # generate some changelog records to accumulate on each MDT
12766         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
12767         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12768                 error "create $DIR/$tdir/$tfile failed"
12769
12770         # check changelogs have been generated
12771         local nbcl=$(changelog_dump | wc -l)
12772         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12773
12774         # reduce the max_idle_indexes value to make sure we exceed it
12775         max_ndx=$((nbcl / 2 - 1))
12776
12777         for param in "changelog_max_idle_indexes=$max_ndx" \
12778                      "changelog_gc=1" \
12779                      "changelog_min_gc_interval=2" \
12780                      "changelog_min_free_cat_entries=3"; do
12781                 local MDT0=$(facet_svc $SINGLEMDS)
12782                 local var="${param%=*}"
12783                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12784
12785                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12786                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
12787                         error "unable to set mdd.*.$param"
12788         done
12789
12790         # simulate changelog catalog almost full
12791         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
12792         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
12793
12794         for i in $(seq $MDSCOUNT); do
12795                 cl_users=(${CL_USERS[mds$i]})
12796                 cl_user1[mds$i]="${cl_users[0]}"
12797                 cl_user2[mds$i]="${cl_users[1]}"
12798
12799                 [ -n "${cl_user1[mds$i]}" ] ||
12800                         error "mds$i: no user registered"
12801                 [ -n "${cl_user2[mds$i]}" ] ||
12802                         error "mds$i: only ${cl_user1[mds$i]} is registered"
12803
12804                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12805                 [ -n "$user_rec1" ] ||
12806                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12807                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12808                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12809                 [ -n "$user_rec2" ] ||
12810                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12811                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12812                      "$user_rec1 + 2 == $user_rec2"
12813                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12814                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12815                               "$user_rec1 + 2, but is $user_rec2"
12816                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12817                 [ -n "$user_rec2" ] ||
12818                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12819                 [ $user_rec1 == $user_rec2 ] ||
12820                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12821                               "$user_rec1, but is $user_rec2"
12822         done
12823
12824         # ensure we are past the previous changelog_min_gc_interval set above
12825         sleep 2
12826
12827         # generate one more changelog to trigger fail_loc
12828         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12829                 error "create $DIR/$tdir/${tfile}bis failed"
12830
12831         # ensure gc thread is done
12832         for i in $(mdts_nodes); do
12833                 wait_update $i \
12834                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
12835                         error "$i: GC-thread not done"
12836         done
12837
12838         local first_rec
12839         for i in $(seq $MDSCOUNT); do
12840                 # check cl_user1 still registered
12841                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
12842                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12843                 # check cl_user2 unregistered
12844                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
12845                         error "mds$i: User ${cl_user2[mds$i]} still registered"
12846
12847                 # check changelogs are present and starting at $user_rec1 + 1
12848                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12849                 [ -n "$user_rec1" ] ||
12850                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12851                 first_rec=$($LFS changelog $(facet_svc mds$i) |
12852                             awk '{ print $1; exit; }')
12853
12854                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
12855                 [ $((user_rec1 + 1)) == $first_rec ] ||
12856                         error "mds$i: first index should be $user_rec1 + 1, " \
12857                               "but is $first_rec"
12858         done
12859 }
12860 run_test 160g "changelog garbage collect (old users)"
12861
12862 test_160h() {
12863         remote_mds_nodsh && skip "remote MDS with nodsh" && return
12864         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12865                 skip "Need MDS version at least 2.10.56"
12866
12867         local mdts=$(comma_list $(mdts_nodes))
12868
12869         # Create a user
12870         changelog_register || error "first changelog_register failed"
12871         changelog_register || error "second changelog_register failed"
12872         local cl_users
12873         declare -A cl_user1
12874         declare -A cl_user2
12875         local user_rec1
12876         local user_rec2
12877         local i
12878
12879         # generate some changelog records to accumulate on each MDT
12880         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
12881         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12882                 error "create $DIR/$tdir/$tfile failed"
12883
12884         # check changelogs have been generated
12885         local nbcl=$(changelog_dump | wc -l)
12886         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12887
12888         for param in "changelog_max_idle_time=10" \
12889                      "changelog_gc=1" \
12890                      "changelog_min_gc_interval=2"; do
12891                 local MDT0=$(facet_svc $SINGLEMDS)
12892                 local var="${param%=*}"
12893                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12894
12895                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12896                 do_nodes $mdts $LCTL set_param mdd.*.$param
12897         done
12898
12899         # force cl_user2 to be idle (1st part)
12900         sleep 9
12901
12902         for i in $(seq $MDSCOUNT); do
12903                 cl_users=(${CL_USERS[mds$i]})
12904                 cl_user1[mds$i]="${cl_users[0]}"
12905                 cl_user2[mds$i]="${cl_users[1]}"
12906
12907                 [ -n "${cl_user1[mds$i]}" ] ||
12908                         error "mds$i: no user registered"
12909                 [ -n "${cl_user2[mds$i]}" ] ||
12910                         error "mds$i: only ${cl_user2[mds$i]} is registered"
12911
12912                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12913                 [ -n "$user_rec1" ] ||
12914                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12915                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12916                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12917                 [ -n "$user_rec2" ] ||
12918                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12919                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12920                      "$user_rec1 + 2 == $user_rec2"
12921                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12922                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12923                               "$user_rec1 + 2, but is $user_rec2"
12924                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12925                 [ -n "$user_rec2" ] ||
12926                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12927                 [ $user_rec1 == $user_rec2 ] ||
12928                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12929                               "$user_rec1, but is $user_rec2"
12930         done
12931
12932         # force cl_user2 to be idle (2nd part) and to reach
12933         # changelog_max_idle_time
12934         sleep 2
12935
12936         # force each GC-thread start and block then
12937         # one per MDT/MDD, set fail_val accordingly
12938         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
12939         do_nodes $mdts $LCTL set_param fail_loc=0x1316
12940
12941         # generate more changelogs to trigger fail_loc
12942         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12943                 error "create $DIR/$tdir/${tfile}bis failed"
12944
12945         # stop MDT to stop GC-thread, should be done in back-ground as it will
12946         # block waiting for the thread to be released and exit
12947         declare -A stop_pids
12948         for i in $(seq $MDSCOUNT); do
12949                 stop mds$i &
12950                 stop_pids[mds$i]=$!
12951         done
12952
12953         for i in $(mdts_nodes); do
12954                 local facet
12955                 local nb=0
12956                 local facets=$(facets_up_on_host $i)
12957
12958                 for facet in ${facets//,/ }; do
12959                         if [[ $facet == mds* ]]; then
12960                                 nb=$((nb + 1))
12961                         fi
12962                 done
12963                 # ensure each MDS's gc threads are still present and all in "R"
12964                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
12965                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
12966                         error "$i: expected $nb GC-thread"
12967                 wait_update $i \
12968                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
12969                         "R" 20 ||
12970                         error "$i: GC-thread not found in R-state"
12971                 # check umounts of each MDT on MDS have reached kthread_stop()
12972                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
12973                         error "$i: expected $nb umount"
12974                 wait_update $i \
12975                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
12976                         error "$i: umount not found in D-state"
12977         done
12978
12979         # release all GC-threads
12980         do_nodes $mdts $LCTL set_param fail_loc=0
12981
12982         # wait for MDT stop to complete
12983         for i in $(seq $MDSCOUNT); do
12984                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
12985         done
12986
12987         # XXX
12988         # may try to check if any orphan changelog records are present
12989         # via ldiskfs/zfs and llog_reader...
12990
12991         # re-start/mount MDTs
12992         for i in $(seq $MDSCOUNT); do
12993                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
12994                         error "Fail to start mds$i"
12995         done
12996
12997         local first_rec
12998         for i in $(seq $MDSCOUNT); do
12999                 # check cl_user1 still registered
13000                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13001                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13002                 # check cl_user2 unregistered
13003                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13004                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13005
13006                 # check changelogs are present and starting at $user_rec1 + 1
13007                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13008                 [ -n "$user_rec1" ] ||
13009                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13010                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13011                             awk '{ print $1; exit; }')
13012
13013                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13014                 [ $((user_rec1 + 1)) == $first_rec ] ||
13015                         error "mds$i: first index should be $user_rec1 + 1, " \
13016                               "but is $first_rec"
13017         done
13018 }
13019 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
13020               "during mount"
13021
13022 test_160i() {
13023
13024         local mdts=$(comma_list $(mdts_nodes))
13025
13026         changelog_register || error "first changelog_register failed"
13027
13028         # generate some changelog records to accumulate on each MDT
13029         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13030         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13031                 error "create $DIR/$tdir/$tfile failed"
13032
13033         # check changelogs have been generated
13034         local nbcl=$(changelog_dump | wc -l)
13035         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13036
13037         # simulate race between register and unregister
13038         # XXX as fail_loc is set per-MDS, with DNE configs the race
13039         # simulation will only occur for one MDT per MDS and for the
13040         # others the normal race scenario will take place
13041         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
13042         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
13043         do_nodes $mdts $LCTL set_param fail_val=1
13044
13045         # unregister 1st user
13046         changelog_deregister &
13047         local pid1=$!
13048         # wait some time for deregister work to reach race rdv
13049         sleep 2
13050         # register 2nd user
13051         changelog_register || error "2nd user register failed"
13052
13053         wait $pid1 || error "1st user deregister failed"
13054
13055         local i
13056         local last_rec
13057         declare -A LAST_REC
13058         for i in $(seq $MDSCOUNT); do
13059                 if changelog_users mds$i | grep "^cl"; then
13060                         # make sure new records are added with one user present
13061                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
13062                                           awk '/^current.index:/ { print $NF }')
13063                 else
13064                         error "mds$i has no user registered"
13065                 fi
13066         done
13067
13068         # generate more changelog records to accumulate on each MDT
13069         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13070                 error "create $DIR/$tdir/${tfile}bis failed"
13071
13072         for i in $(seq $MDSCOUNT); do
13073                 last_rec=$(changelog_users $SINGLEMDS |
13074                            awk '/^current.index:/ { print $NF }')
13075                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
13076                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
13077                         error "changelogs are off on mds$i"
13078         done
13079 }
13080 run_test 160i "changelog user register/unregister race"
13081
13082 test_161a() {
13083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13084
13085         test_mkdir -c1 $DIR/$tdir
13086         cp /etc/hosts $DIR/$tdir/$tfile
13087         test_mkdir -c1 $DIR/$tdir/foo1
13088         test_mkdir -c1 $DIR/$tdir/foo2
13089         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
13090         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
13091         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
13092         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
13093         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
13094         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13095                 $LFS fid2path $DIR $FID
13096                 error "bad link ea"
13097         fi
13098         # middle
13099         rm $DIR/$tdir/foo2/zachary
13100         # last
13101         rm $DIR/$tdir/foo2/thor
13102         # first
13103         rm $DIR/$tdir/$tfile
13104         # rename
13105         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
13106         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
13107                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
13108         rm $DIR/$tdir/foo2/maggie
13109
13110         # overflow the EA
13111         local longname=$tfile.avg_len_is_thirty_two_
13112         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
13113                 error_noexit 'failed to unlink many hardlinks'" EXIT
13114         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
13115                 error "failed to hardlink many files"
13116         links=$($LFS fid2path $DIR $FID | wc -l)
13117         echo -n "${links}/1000 links in link EA"
13118         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
13119 }
13120 run_test 161a "link ea sanity"
13121
13122 test_161b() {
13123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13124         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
13125
13126         local MDTIDX=1
13127         local remote_dir=$DIR/$tdir/remote_dir
13128
13129         mkdir -p $DIR/$tdir
13130         $LFS mkdir -i $MDTIDX $remote_dir ||
13131                 error "create remote directory failed"
13132
13133         cp /etc/hosts $remote_dir/$tfile
13134         mkdir -p $remote_dir/foo1
13135         mkdir -p $remote_dir/foo2
13136         ln $remote_dir/$tfile $remote_dir/foo1/sofia
13137         ln $remote_dir/$tfile $remote_dir/foo2/zachary
13138         ln $remote_dir/$tfile $remote_dir/foo1/luna
13139         ln $remote_dir/$tfile $remote_dir/foo2/thor
13140
13141         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
13142                      tr -d ']')
13143         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13144                 $LFS fid2path $DIR $FID
13145                 error "bad link ea"
13146         fi
13147         # middle
13148         rm $remote_dir/foo2/zachary
13149         # last
13150         rm $remote_dir/foo2/thor
13151         # first
13152         rm $remote_dir/$tfile
13153         # rename
13154         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
13155         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
13156         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
13157                 $LFS fid2path $DIR $FID
13158                 error "bad link rename"
13159         fi
13160         rm $remote_dir/foo2/maggie
13161
13162         # overflow the EA
13163         local longname=filename_avg_len_is_thirty_two_
13164         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
13165                 error "failed to hardlink many files"
13166         links=$($LFS fid2path $DIR $FID | wc -l)
13167         echo -n "${links}/1000 links in link EA"
13168         [[ ${links} -gt 60 ]] ||
13169                 error "expected at least 60 links in link EA"
13170         unlinkmany $remote_dir/foo2/$longname 1000 ||
13171         error "failed to unlink many hardlinks"
13172 }
13173 run_test 161b "link ea sanity under remote directory"
13174
13175 test_161c() {
13176         remote_mds_nodsh && skip "remote MDS with nodsh"
13177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13178         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
13179                 skip "Need MDS version at least 2.1.5"
13180
13181         # define CLF_RENAME_LAST 0x0001
13182         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
13183         changelog_register || error "changelog_register failed"
13184
13185         rm -rf $DIR/$tdir
13186         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
13187         touch $DIR/$tdir/foo_161c
13188         touch $DIR/$tdir/bar_161c
13189         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13190         changelog_dump | grep RENME | tail -n 5
13191         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13192         changelog_clear 0 || error "changelog_clear failed"
13193         if [ x$flags != "x0x1" ]; then
13194                 error "flag $flags is not 0x1"
13195         fi
13196
13197         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
13198         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
13199         touch $DIR/$tdir/foo_161c
13200         touch $DIR/$tdir/bar_161c
13201         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13202         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13203         changelog_dump | grep RENME | tail -n 5
13204         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13205         changelog_clear 0 || error "changelog_clear failed"
13206         if [ x$flags != "x0x0" ]; then
13207                 error "flag $flags is not 0x0"
13208         fi
13209         echo "rename overwrite a target having nlink > 1," \
13210                 "changelog record has flags of $flags"
13211
13212         # rename doesn't overwrite a target (changelog flag 0x0)
13213         touch $DIR/$tdir/foo_161c
13214         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
13215         changelog_dump | grep RENME | tail -n 5
13216         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
13217         changelog_clear 0 || error "changelog_clear failed"
13218         if [ x$flags != "x0x0" ]; then
13219                 error "flag $flags is not 0x0"
13220         fi
13221         echo "rename doesn't overwrite a target," \
13222                 "changelog record has flags of $flags"
13223
13224         # define CLF_UNLINK_LAST 0x0001
13225         # unlink a file having nlink = 1 (changelog flag 0x1)
13226         rm -f $DIR/$tdir/foo2_161c
13227         changelog_dump | grep UNLNK | tail -n 5
13228         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13229         changelog_clear 0 || error "changelog_clear failed"
13230         if [ x$flags != "x0x1" ]; then
13231                 error "flag $flags is not 0x1"
13232         fi
13233         echo "unlink a file having nlink = 1," \
13234                 "changelog record has flags of $flags"
13235
13236         # unlink a file having nlink > 1 (changelog flag 0x0)
13237         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13238         rm -f $DIR/$tdir/foobar_161c
13239         changelog_dump | grep UNLNK | tail -n 5
13240         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13241         changelog_clear 0 || error "changelog_clear failed"
13242         if [ x$flags != "x0x0" ]; then
13243                 error "flag $flags is not 0x0"
13244         fi
13245         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
13246 }
13247 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
13248
13249 test_161d() {
13250         remote_mds_nodsh && skip "remote MDS with nodsh"
13251         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
13252
13253         local pid
13254         local fid
13255
13256         changelog_register || error "changelog_register failed"
13257
13258         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
13259         # interfer with $MOUNT/.lustre/fid/ access
13260         mkdir $DIR/$tdir
13261         [[ $? -eq 0 ]] || error "mkdir failed"
13262
13263         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
13264         $LCTL set_param fail_loc=0x8000140c
13265         # 5s pause
13266         $LCTL set_param fail_val=5
13267
13268         # create file
13269         echo foofoo > $DIR/$tdir/$tfile &
13270         pid=$!
13271
13272         # wait for create to be delayed
13273         sleep 2
13274
13275         ps -p $pid
13276         [[ $? -eq 0 ]] || error "create should be blocked"
13277
13278         local tempfile=$(mktemp)
13279         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
13280         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
13281         # some delay may occur during ChangeLog publishing and file read just
13282         # above, that could allow file write to happen finally
13283         [[ -s $tempfile ]] && echo "file should be empty"
13284
13285         $LCTL set_param fail_loc=0
13286
13287         wait $pid
13288         [[ $? -eq 0 ]] || error "create failed"
13289 }
13290 run_test 161d "create with concurrent .lustre/fid access"
13291
13292 check_path() {
13293         local expected="$1"
13294         shift
13295         local fid="$2"
13296
13297         local path
13298         path=$($LFS fid2path "$@")
13299         local rc=$?
13300
13301         if [ $rc -ne 0 ]; then
13302                 error "path looked up of '$expected' failed: rc=$rc"
13303         elif [ "$path" != "$expected" ]; then
13304                 error "path looked up '$path' instead of '$expected'"
13305         else
13306                 echo "FID '$fid' resolves to path '$path' as expected"
13307         fi
13308 }
13309
13310 test_162a() { # was test_162
13311         test_mkdir -p -c1 $DIR/$tdir/d2
13312         touch $DIR/$tdir/d2/$tfile
13313         touch $DIR/$tdir/d2/x1
13314         touch $DIR/$tdir/d2/x2
13315         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
13316         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
13317         # regular file
13318         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
13319         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
13320
13321         # softlink
13322         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
13323         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
13324         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
13325
13326         # softlink to wrong file
13327         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
13328         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
13329         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
13330
13331         # hardlink
13332         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
13333         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
13334         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
13335         # fid2path dir/fsname should both work
13336         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
13337         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
13338
13339         # hardlink count: check that there are 2 links
13340         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
13341         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
13342
13343         # hardlink indexing: remove the first link
13344         rm $DIR/$tdir/d2/p/q/r/hlink
13345         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
13346 }
13347 run_test 162a "path lookup sanity"
13348
13349 test_162b() {
13350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13351         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13352
13353         mkdir $DIR/$tdir
13354         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
13355                                 error "create striped dir failed"
13356
13357         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
13358                                         tail -n 1 | awk '{print $2}')
13359         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
13360
13361         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
13362         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
13363
13364         # regular file
13365         for ((i=0;i<5;i++)); do
13366                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
13367                         error "get fid for f$i failed"
13368                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
13369
13370                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
13371                         error "get fid for d$i failed"
13372                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
13373         done
13374
13375         return 0
13376 }
13377 run_test 162b "striped directory path lookup sanity"
13378
13379 # LU-4239: Verify fid2path works with paths 100 or more directories deep
13380 test_162c() {
13381         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
13382                 skip "Need MDS version at least 2.7.51"
13383
13384         local lpath=$tdir.local
13385         local rpath=$tdir.remote
13386
13387         test_mkdir $DIR/$lpath
13388         test_mkdir $DIR/$rpath
13389
13390         for ((i = 0; i <= 101; i++)); do
13391                 lpath="$lpath/$i"
13392                 mkdir $DIR/$lpath
13393                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
13394                         error "get fid for local directory $DIR/$lpath failed"
13395                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
13396
13397                 rpath="$rpath/$i"
13398                 test_mkdir $DIR/$rpath
13399                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
13400                         error "get fid for remote directory $DIR/$rpath failed"
13401                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
13402         done
13403
13404         return 0
13405 }
13406 run_test 162c "fid2path works with paths 100 or more directories deep"
13407
13408 test_169() {
13409         # do directio so as not to populate the page cache
13410         log "creating a 10 Mb file"
13411         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
13412         log "starting reads"
13413         dd if=$DIR/$tfile of=/dev/null bs=4096 &
13414         log "truncating the file"
13415         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
13416         log "killing dd"
13417         kill %+ || true # reads might have finished
13418         echo "wait until dd is finished"
13419         wait
13420         log "removing the temporary file"
13421         rm -rf $DIR/$tfile || error "tmp file removal failed"
13422 }
13423 run_test 169 "parallel read and truncate should not deadlock"
13424
13425 test_170() {
13426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13427
13428         $LCTL clear     # bug 18514
13429         $LCTL debug_daemon start $TMP/${tfile}_log_good
13430         touch $DIR/$tfile
13431         $LCTL debug_daemon stop
13432         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
13433                 error "sed failed to read log_good"
13434
13435         $LCTL debug_daemon start $TMP/${tfile}_log_good
13436         rm -rf $DIR/$tfile
13437         $LCTL debug_daemon stop
13438
13439         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
13440                error "lctl df log_bad failed"
13441
13442         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13443         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13444
13445         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
13446         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
13447
13448         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
13449                 error "bad_line good_line1 good_line2 are empty"
13450
13451         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13452         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
13453         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13454
13455         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
13456         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13457         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13458
13459         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
13460                 error "bad_line_new good_line_new are empty"
13461
13462         local expected_good=$((good_line1 + good_line2*2))
13463
13464         rm -f $TMP/${tfile}*
13465         # LU-231, short malformed line may not be counted into bad lines
13466         if [ $bad_line -ne $bad_line_new ] &&
13467                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
13468                 error "expected $bad_line bad lines, but got $bad_line_new"
13469                 return 1
13470         fi
13471
13472         if [ $expected_good -ne $good_line_new ]; then
13473                 error "expected $expected_good good lines, but got $good_line_new"
13474                 return 2
13475         fi
13476         true
13477 }
13478 run_test 170 "test lctl df to handle corrupted log ====================="
13479
13480 test_171() { # bug20592
13481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13482
13483         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
13484         $LCTL set_param fail_loc=0x50e
13485         $LCTL set_param fail_val=3000
13486         multiop_bg_pause $DIR/$tfile O_s || true
13487         local MULTIPID=$!
13488         kill -USR1 $MULTIPID
13489         # cause log dump
13490         sleep 3
13491         wait $MULTIPID
13492         if dmesg | grep "recursive fault"; then
13493                 error "caught a recursive fault"
13494         fi
13495         $LCTL set_param fail_loc=0
13496         true
13497 }
13498 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
13499
13500 # it would be good to share it with obdfilter-survey/iokit-libecho code
13501 setup_obdecho_osc () {
13502         local rc=0
13503         local ost_nid=$1
13504         local obdfilter_name=$2
13505         echo "Creating new osc for $obdfilter_name on $ost_nid"
13506         # make sure we can find loopback nid
13507         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
13508
13509         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
13510                            ${obdfilter_name}_osc_UUID || rc=2; }
13511         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
13512                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
13513         return $rc
13514 }
13515
13516 cleanup_obdecho_osc () {
13517         local obdfilter_name=$1
13518         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
13519         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
13520         return 0
13521 }
13522
13523 obdecho_test() {
13524         local OBD=$1
13525         local node=$2
13526         local pages=${3:-64}
13527         local rc=0
13528         local id
13529
13530         local count=10
13531         local obd_size=$(get_obd_size $node $OBD)
13532         local page_size=$(get_page_size $node)
13533         if [[ -n "$obd_size" ]]; then
13534                 local new_count=$((obd_size / (pages * page_size / 1024)))
13535                 [[ $new_count -ge $count ]] || count=$new_count
13536         fi
13537
13538         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
13539         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
13540                            rc=2; }
13541         if [ $rc -eq 0 ]; then
13542             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
13543             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
13544         fi
13545         echo "New object id is $id"
13546         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
13547                            rc=4; }
13548         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
13549                            "test_brw $count w v $pages $id" || rc=4; }
13550         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
13551                            rc=4; }
13552         [ $rc -eq 0 -o $rc -gt 2 ] && { do_facet $node "$LCTL --device ec "    \
13553                                         "cleanup" || rc=5; }
13554         [ $rc -eq 0 -o $rc -gt 1 ] && { do_facet $node "$LCTL --device ec "    \
13555                                         "detach" || rc=6; }
13556         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
13557         return $rc
13558 }
13559
13560 test_180a() {
13561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13562
13563         if ! module_loaded obdecho; then
13564                 load_module obdecho/obdecho &&
13565                         stack_trap "rmmod obdecho" EXIT ||
13566                         error "unable to load obdecho on client"
13567         fi
13568
13569         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
13570         local host=$($LCTL get_param -n osc.$osc.import |
13571                      awk '/current_connection:/ { print $2 }' )
13572         local target=$($LCTL get_param -n osc.$osc.import |
13573                        awk '/target:/ { print $2 }' )
13574         target=${target%_UUID}
13575
13576         if [ -n "$target" ]; then
13577                 setup_obdecho_osc $host $target &&
13578                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
13579                         { error "obdecho setup failed with $?"; return; }
13580
13581                 obdecho_test ${target}_osc client ||
13582                         error "obdecho_test failed on ${target}_osc"
13583         else
13584                 $LCTL get_param osc.$osc.import
13585                 error "there is no osc.$osc.import target"
13586         fi
13587 }
13588 run_test 180a "test obdecho on osc"
13589
13590 test_180b() {
13591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13592         remote_ost_nodsh && skip "remote OST with nodsh"
13593
13594         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
13595                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
13596                 error "failed to load module obdecho"
13597
13598         local target=$(do_facet ost1 $LCTL dl |
13599                        awk '/obdfilter/ { print $4; exit; }')
13600
13601         if [ -n "$target" ]; then
13602                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
13603         else
13604                 do_facet ost1 $LCTL dl
13605                 error "there is no obdfilter target on ost1"
13606         fi
13607 }
13608 run_test 180b "test obdecho directly on obdfilter"
13609
13610 test_180c() { # LU-2598
13611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13612         remote_ost_nodsh && skip "remote OST with nodsh"
13613         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
13614                 skip "Need MDS version at least 2.4.0"
13615
13616         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
13617                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
13618                 error "failed to load module obdecho"
13619
13620         local target=$(do_facet ost1 $LCTL dl |
13621                        awk '/obdfilter/ { print $4; exit; }')
13622
13623         if [ -n "$target" ]; then
13624                 local pages=16384 # 64MB bulk I/O RPC size
13625
13626                 obdecho_test "$target" ost1 "$pages" ||
13627                         error "obdecho_test with pages=$pages failed with $?"
13628         else
13629                 do_facet ost1 $LCTL dl
13630                 error "there is no obdfilter target on ost1"
13631         fi
13632 }
13633 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
13634
13635 test_181() { # bug 22177
13636         test_mkdir $DIR/$tdir
13637         # create enough files to index the directory
13638         createmany -o $DIR/$tdir/foobar 4000
13639         # print attributes for debug purpose
13640         lsattr -d .
13641         # open dir
13642         multiop_bg_pause $DIR/$tdir D_Sc || return 1
13643         MULTIPID=$!
13644         # remove the files & current working dir
13645         unlinkmany $DIR/$tdir/foobar 4000
13646         rmdir $DIR/$tdir
13647         kill -USR1 $MULTIPID
13648         wait $MULTIPID
13649         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
13650         return 0
13651 }
13652 run_test 181 "Test open-unlinked dir ========================"
13653
13654 test_182() {
13655         local fcount=1000
13656         local tcount=10
13657
13658         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13659
13660         $LCTL set_param mdc.*.rpc_stats=clear
13661
13662         for (( i = 0; i < $tcount; i++ )) ; do
13663                 mkdir $DIR/$tdir/$i
13664         done
13665
13666         for (( i = 0; i < $tcount; i++ )) ; do
13667                 createmany -o $DIR/$tdir/$i/f- $fcount &
13668         done
13669         wait
13670
13671         for (( i = 0; i < $tcount; i++ )) ; do
13672                 unlinkmany $DIR/$tdir/$i/f- $fcount &
13673         done
13674         wait
13675
13676         $LCTL get_param mdc.*.rpc_stats
13677
13678         rm -rf $DIR/$tdir
13679 }
13680 run_test 182 "Test parallel modify metadata operations ================"
13681
13682 test_183() { # LU-2275
13683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13684         remote_mds_nodsh && skip "remote MDS with nodsh"
13685         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
13686                 skip "Need MDS version at least 2.3.56"
13687
13688         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13689         echo aaa > $DIR/$tdir/$tfile
13690
13691 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
13692         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
13693
13694         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
13695         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
13696
13697         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
13698
13699         # Flush negative dentry cache
13700         touch $DIR/$tdir/$tfile
13701
13702         # We are not checking for any leaked references here, they'll
13703         # become evident next time we do cleanup with module unload.
13704         rm -rf $DIR/$tdir
13705 }
13706 run_test 183 "No crash or request leak in case of strange dispositions ========"
13707
13708 # test suite 184 is for LU-2016, LU-2017
13709 test_184a() {
13710         check_swap_layouts_support
13711
13712         dir0=$DIR/$tdir/$testnum
13713         test_mkdir -p -c1 $dir0
13714         ref1=/etc/passwd
13715         ref2=/etc/group
13716         file1=$dir0/f1
13717         file2=$dir0/f2
13718         $LFS setstripe -c1 $file1
13719         cp $ref1 $file1
13720         $LFS setstripe -c2 $file2
13721         cp $ref2 $file2
13722         gen1=$($LFS getstripe -g $file1)
13723         gen2=$($LFS getstripe -g $file2)
13724
13725         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
13726         gen=$($LFS getstripe -g $file1)
13727         [[ $gen1 != $gen ]] ||
13728                 "Layout generation on $file1 does not change"
13729         gen=$($LFS getstripe -g $file2)
13730         [[ $gen2 != $gen ]] ||
13731                 "Layout generation on $file2 does not change"
13732
13733         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
13734         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
13735
13736         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
13737 }
13738 run_test 184a "Basic layout swap"
13739
13740 test_184b() {
13741         check_swap_layouts_support
13742
13743         dir0=$DIR/$tdir/$testnum
13744         mkdir -p $dir0 || error "creating dir $dir0"
13745         file1=$dir0/f1
13746         file2=$dir0/f2
13747         file3=$dir0/f3
13748         dir1=$dir0/d1
13749         dir2=$dir0/d2
13750         mkdir $dir1 $dir2
13751         $LFS setstripe -c1 $file1
13752         $LFS setstripe -c2 $file2
13753         $LFS setstripe -c1 $file3
13754         chown $RUNAS_ID $file3
13755         gen1=$($LFS getstripe -g $file1)
13756         gen2=$($LFS getstripe -g $file2)
13757
13758         $LFS swap_layouts $dir1 $dir2 &&
13759                 error "swap of directories layouts should fail"
13760         $LFS swap_layouts $dir1 $file1 &&
13761                 error "swap of directory and file layouts should fail"
13762         $RUNAS $LFS swap_layouts $file1 $file2 &&
13763                 error "swap of file we cannot write should fail"
13764         $LFS swap_layouts $file1 $file3 &&
13765                 error "swap of file with different owner should fail"
13766         /bin/true # to clear error code
13767 }
13768 run_test 184b "Forbidden layout swap (will generate errors)"
13769
13770 test_184c() {
13771         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
13772         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
13773         check_swap_layouts_support
13774
13775         local dir0=$DIR/$tdir/$testnum
13776         mkdir -p $dir0 || error "creating dir $dir0"
13777
13778         local ref1=$dir0/ref1
13779         local ref2=$dir0/ref2
13780         local file1=$dir0/file1
13781         local file2=$dir0/file2
13782         # create a file large enough for the concurrent test
13783         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
13784         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
13785         echo "ref file size: ref1($(stat -c %s $ref1))," \
13786              "ref2($(stat -c %s $ref2))"
13787
13788         cp $ref2 $file2
13789         dd if=$ref1 of=$file1 bs=16k &
13790         local DD_PID=$!
13791
13792         # Make sure dd starts to copy file
13793         while [ ! -f $file1 ]; do sleep 0.1; done
13794
13795         $LFS swap_layouts $file1 $file2
13796         local rc=$?
13797         wait $DD_PID
13798         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
13799         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
13800
13801         # how many bytes copied before swapping layout
13802         local copied=$(stat -c %s $file2)
13803         local remaining=$(stat -c %s $ref1)
13804         remaining=$((remaining - copied))
13805         echo "Copied $copied bytes before swapping layout..."
13806
13807         cmp -n $copied $file1 $ref2 | grep differ &&
13808                 error "Content mismatch [0, $copied) of ref2 and file1"
13809         cmp -n $copied $file2 $ref1 ||
13810                 error "Content mismatch [0, $copied) of ref1 and file2"
13811         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
13812                 error "Content mismatch [$copied, EOF) of ref1 and file1"
13813
13814         # clean up
13815         rm -f $ref1 $ref2 $file1 $file2
13816 }
13817 run_test 184c "Concurrent write and layout swap"
13818
13819 test_184d() {
13820         check_swap_layouts_support
13821         [ -z "$(which getfattr 2>/dev/null)" ] &&
13822                 skip_env "no getfattr command"
13823
13824         local file1=$DIR/$tdir/$tfile-1
13825         local file2=$DIR/$tdir/$tfile-2
13826         local file3=$DIR/$tdir/$tfile-3
13827         local lovea1
13828         local lovea2
13829
13830         mkdir -p $DIR/$tdir
13831         touch $file1 || error "create $file1 failed"
13832         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
13833                 error "create $file2 failed"
13834         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
13835                 error "create $file3 failed"
13836         lovea1=$(get_layout_param $file1)
13837
13838         $LFS swap_layouts $file2 $file3 ||
13839                 error "swap $file2 $file3 layouts failed"
13840         $LFS swap_layouts $file1 $file2 ||
13841                 error "swap $file1 $file2 layouts failed"
13842
13843         lovea2=$(get_layout_param $file2)
13844         echo "$lovea1"
13845         echo "$lovea2"
13846         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
13847
13848         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
13849         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
13850 }
13851 run_test 184d "allow stripeless layouts swap"
13852
13853 test_184e() {
13854         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
13855                 skip "Need MDS version at least 2.6.94"
13856         check_swap_layouts_support
13857         [ -z "$(which getfattr 2>/dev/null)" ] &&
13858                 skip_env "no getfattr command"
13859
13860         local file1=$DIR/$tdir/$tfile-1
13861         local file2=$DIR/$tdir/$tfile-2
13862         local file3=$DIR/$tdir/$tfile-3
13863         local lovea
13864
13865         mkdir -p $DIR/$tdir
13866         touch $file1 || error "create $file1 failed"
13867         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
13868                 error "create $file2 failed"
13869         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
13870                 error "create $file3 failed"
13871
13872         $LFS swap_layouts $file1 $file2 ||
13873                 error "swap $file1 $file2 layouts failed"
13874
13875         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
13876         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
13877
13878         echo 123 > $file1 || error "Should be able to write into $file1"
13879
13880         $LFS swap_layouts $file1 $file3 ||
13881                 error "swap $file1 $file3 layouts failed"
13882
13883         echo 123 > $file1 || error "Should be able to write into $file1"
13884
13885         rm -rf $file1 $file2 $file3
13886 }
13887 run_test 184e "Recreate layout after stripeless layout swaps"
13888
13889 test_184f() {
13890         # Create a file with name longer than sizeof(struct stat) ==
13891         # 144 to see if we can get chars from the file name to appear
13892         # in the returned striping. Note that 'f' == 0x66.
13893         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
13894
13895         mkdir -p $DIR/$tdir
13896         mcreate $DIR/$tdir/$file
13897         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
13898                 error "IOC_MDC_GETFILEINFO returned garbage striping"
13899         fi
13900 }
13901 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
13902
13903 test_185() { # LU-2441
13904         # LU-3553 - no volatile file support in old servers
13905         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
13906                 skip "Need MDS version at least 2.3.60"
13907
13908         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13909         touch $DIR/$tdir/spoo
13910         local mtime1=$(stat -c "%Y" $DIR/$tdir)
13911         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
13912                 error "cannot create/write a volatile file"
13913         [ "$FILESET" == "" ] &&
13914         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
13915                 error "FID is still valid after close"
13916
13917         multiop_bg_pause $DIR/$tdir vVw4096_c
13918         local multi_pid=$!
13919
13920         local OLD_IFS=$IFS
13921         IFS=":"
13922         local fidv=($fid)
13923         IFS=$OLD_IFS
13924         # assume that the next FID for this client is sequential, since stdout
13925         # is unfortunately eaten by multiop_bg_pause
13926         local n=$((${fidv[1]} + 1))
13927         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
13928         if [ "$FILESET" == "" ]; then
13929                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
13930                         error "FID is missing before close"
13931         fi
13932         kill -USR1 $multi_pid
13933         # 1 second delay, so if mtime change we will see it
13934         sleep 1
13935         local mtime2=$(stat -c "%Y" $DIR/$tdir)
13936         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
13937 }
13938 run_test 185 "Volatile file support"
13939
13940 test_187a() {
13941         remote_mds_nodsh && skip "remote MDS with nodsh"
13942         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
13943                 skip "Need MDS version at least 2.3.0"
13944
13945         local dir0=$DIR/$tdir/$testnum
13946         mkdir -p $dir0 || error "creating dir $dir0"
13947
13948         local file=$dir0/file1
13949         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
13950         local dv1=$($LFS data_version $file)
13951         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
13952         local dv2=$($LFS data_version $file)
13953         [[ $dv1 != $dv2 ]] ||
13954                 error "data version did not change on write $dv1 == $dv2"
13955
13956         # clean up
13957         rm -f $file1
13958 }
13959 run_test 187a "Test data version change"
13960
13961 test_187b() {
13962         remote_mds_nodsh && skip "remote MDS with nodsh"
13963         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
13964                 skip "Need MDS version at least 2.3.0"
13965
13966         local dir0=$DIR/$tdir/$testnum
13967         mkdir -p $dir0 || error "creating dir $dir0"
13968
13969         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
13970         [[ ${DV[0]} != ${DV[1]} ]] ||
13971                 error "data version did not change on write"\
13972                       " ${DV[0]} == ${DV[1]}"
13973
13974         # clean up
13975         rm -f $file1
13976 }
13977 run_test 187b "Test data version change on volatile file"
13978
13979 test_200() {
13980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13981         remote_mgs_nodsh && skip "remote MGS with nodsh"
13982         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13983
13984         local POOL=${POOL:-cea1}
13985         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
13986         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
13987         # Pool OST targets
13988         local first_ost=0
13989         local last_ost=$(($OSTCOUNT - 1))
13990         local ost_step=2
13991         local ost_list=$(seq $first_ost $ost_step $last_ost)
13992         local ost_range="$first_ost $last_ost $ost_step"
13993         local test_path=$POOL_ROOT/$POOL_DIR_NAME
13994         local file_dir=$POOL_ROOT/file_tst
13995         local subdir=$test_path/subdir
13996         local rc=0
13997
13998         if ! combined_mgs_mds ; then
13999                 mount_mgs_client
14000         fi
14001
14002         while : ; do
14003                 # former test_200a test_200b
14004                 pool_add $POOL                          || { rc=$? ; break; }
14005                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
14006                 # former test_200c test_200d
14007                 mkdir -p $test_path
14008                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
14009                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
14010                 mkdir -p $subdir
14011                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
14012                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
14013                                                         || { rc=$? ; break; }
14014                 # former test_200e test_200f
14015                 local files=$((OSTCOUNT*3))
14016                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
14017                                                         || { rc=$? ; break; }
14018                 pool_create_files $POOL $file_dir $files "$ost_list" \
14019                                                         || { rc=$? ; break; }
14020                 # former test_200g test_200h
14021                 pool_lfs_df $POOL                       || { rc=$? ; break; }
14022                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
14023
14024                 # former test_201a test_201b test_201c
14025                 pool_remove_first_target $POOL          || { rc=$? ; break; }
14026
14027                 local f=$test_path/$tfile
14028                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
14029                 pool_remove $POOL $f                    || { rc=$? ; break; }
14030                 break
14031         done
14032
14033         destroy_test_pools
14034
14035         if ! combined_mgs_mds ; then
14036                 umount_mgs_client
14037         fi
14038         return $rc
14039 }
14040 run_test 200 "OST pools"
14041
14042 # usage: default_attr <count | size | offset>
14043 default_attr() {
14044         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
14045 }
14046
14047 # usage: check_default_stripe_attr
14048 check_default_stripe_attr() {
14049         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
14050         case $1 in
14051         --stripe-count|-c)
14052                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
14053         --stripe-size|-S)
14054                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
14055         --stripe-index|-i)
14056                 EXPECTED=-1;;
14057         *)
14058                 error "unknown getstripe attr '$1'"
14059         esac
14060
14061         [ $ACTUAL == $EXPECTED ] ||
14062                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
14063 }
14064
14065 test_204a() {
14066         test_mkdir $DIR/$tdir
14067         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
14068
14069         check_default_stripe_attr --stripe-count
14070         check_default_stripe_attr --stripe-size
14071         check_default_stripe_attr --stripe-index
14072 }
14073 run_test 204a "Print default stripe attributes"
14074
14075 test_204b() {
14076         test_mkdir $DIR/$tdir
14077         $LFS setstripe --stripe-count 1 $DIR/$tdir
14078
14079         check_default_stripe_attr --stripe-size
14080         check_default_stripe_attr --stripe-index
14081 }
14082 run_test 204b "Print default stripe size and offset"
14083
14084 test_204c() {
14085         test_mkdir $DIR/$tdir
14086         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14087
14088         check_default_stripe_attr --stripe-count
14089         check_default_stripe_attr --stripe-index
14090 }
14091 run_test 204c "Print default stripe count and offset"
14092
14093 test_204d() {
14094         test_mkdir $DIR/$tdir
14095         $LFS setstripe --stripe-index 0 $DIR/$tdir
14096
14097         check_default_stripe_attr --stripe-count
14098         check_default_stripe_attr --stripe-size
14099 }
14100 run_test 204d "Print default stripe count and size"
14101
14102 test_204e() {
14103         test_mkdir $DIR/$tdir
14104         $LFS setstripe -d $DIR/$tdir
14105
14106         check_default_stripe_attr --stripe-count --raw
14107         check_default_stripe_attr --stripe-size --raw
14108         check_default_stripe_attr --stripe-index --raw
14109 }
14110 run_test 204e "Print raw stripe attributes"
14111
14112 test_204f() {
14113         test_mkdir $DIR/$tdir
14114         $LFS setstripe --stripe-count 1 $DIR/$tdir
14115
14116         check_default_stripe_attr --stripe-size --raw
14117         check_default_stripe_attr --stripe-index --raw
14118 }
14119 run_test 204f "Print raw stripe size and offset"
14120
14121 test_204g() {
14122         test_mkdir $DIR/$tdir
14123         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14124
14125         check_default_stripe_attr --stripe-count --raw
14126         check_default_stripe_attr --stripe-index --raw
14127 }
14128 run_test 204g "Print raw stripe count and offset"
14129
14130 test_204h() {
14131         test_mkdir $DIR/$tdir
14132         $LFS setstripe --stripe-index 0 $DIR/$tdir
14133
14134         check_default_stripe_attr --stripe-count --raw
14135         check_default_stripe_attr --stripe-size --raw
14136 }
14137 run_test 204h "Print raw stripe count and size"
14138
14139 # Figure out which job scheduler is being used, if any,
14140 # or use a fake one
14141 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
14142         JOBENV=SLURM_JOB_ID
14143 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
14144         JOBENV=LSB_JOBID
14145 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
14146         JOBENV=PBS_JOBID
14147 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
14148         JOBENV=LOADL_STEP_ID
14149 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
14150         JOBENV=JOB_ID
14151 else
14152         $LCTL list_param jobid_name > /dev/null 2>&1
14153         if [ $? -eq 0 ]; then
14154                 JOBENV=nodelocal
14155         else
14156                 JOBENV=FAKE_JOBID
14157         fi
14158 fi
14159 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
14160
14161 verify_jobstats() {
14162         local cmd=($1)
14163         shift
14164         local facets="$@"
14165
14166 # we don't really need to clear the stats for this test to work, since each
14167 # command has a unique jobid, but it makes debugging easier if needed.
14168 #       for facet in $facets; do
14169 #               local dev=$(convert_facet2label $facet)
14170 #               # clear old jobstats
14171 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
14172 #       done
14173
14174         # use a new JobID for each test, or we might see an old one
14175         [ "$JOBENV" = "FAKE_JOBID" ] &&
14176                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
14177
14178         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
14179
14180         [ "$JOBENV" = "nodelocal" ] && {
14181                 FAKE_JOBID=id.$testnum.%e.$RANDOM
14182                 $LCTL set_param jobid_name=$FAKE_JOBID
14183                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
14184         }
14185
14186         log "Test: ${cmd[*]}"
14187         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
14188
14189         if [ $JOBENV = "FAKE_JOBID" ]; then
14190                 FAKE_JOBID=$JOBVAL ${cmd[*]}
14191         else
14192                 ${cmd[*]}
14193         fi
14194
14195         # all files are created on OST0000
14196         for facet in $facets; do
14197                 local stats="*.$(convert_facet2label $facet).job_stats"
14198
14199                 # strip out libtool wrappers for in-tree executables
14200                 if [ $(do_facet $facet lctl get_param $stats |
14201                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
14202                         do_facet $facet lctl get_param $stats
14203                         error "No jobstats for $JOBVAL found on $facet::$stats"
14204                 fi
14205         done
14206 }
14207
14208 jobstats_set() {
14209         local new_jobenv=$1
14210
14211         set_persistent_param_and_check client "jobid_var" \
14212                 "$FSNAME.sys.jobid_var" $new_jobenv
14213 }
14214
14215 test_205() { # Job stats
14216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14217         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
14218                 skip "Need MDS version with at least 2.7.1"
14219         remote_mgs_nodsh && skip "remote MGS with nodsh"
14220         remote_mds_nodsh && skip "remote MDS with nodsh"
14221         remote_ost_nodsh && skip "remote OST with nodsh"
14222         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
14223                 skip "Server doesn't support jobstats"
14224         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
14225
14226         local old_jobenv=$($LCTL get_param -n jobid_var)
14227         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
14228
14229         if [[ $PERM_CMD == *"set_param -P"* ]]; then
14230                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
14231         else
14232                 stack_trap "do_facet mgs $PERM_CMD \
14233                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
14234         fi
14235         changelog_register
14236
14237         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
14238                                 mdt.*.job_cleanup_interval | head -n 1)
14239         local new_interval=5
14240         do_facet $SINGLEMDS \
14241                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
14242         stack_trap "do_facet $SINGLEMDS \
14243                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
14244         local start=$SECONDS
14245
14246         local cmd
14247         # mkdir
14248         cmd="mkdir $DIR/$tdir"
14249         verify_jobstats "$cmd" "$SINGLEMDS"
14250         # rmdir
14251         cmd="rmdir $DIR/$tdir"
14252         verify_jobstats "$cmd" "$SINGLEMDS"
14253         # mkdir on secondary MDT
14254         if [ $MDSCOUNT -gt 1 ]; then
14255                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
14256                 verify_jobstats "$cmd" "mds2"
14257         fi
14258         # mknod
14259         cmd="mknod $DIR/$tfile c 1 3"
14260         verify_jobstats "$cmd" "$SINGLEMDS"
14261         # unlink
14262         cmd="rm -f $DIR/$tfile"
14263         verify_jobstats "$cmd" "$SINGLEMDS"
14264         # create all files on OST0000 so verify_jobstats can find OST stats
14265         # open & close
14266         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
14267         verify_jobstats "$cmd" "$SINGLEMDS"
14268         # setattr
14269         cmd="touch $DIR/$tfile"
14270         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14271         # write
14272         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
14273         verify_jobstats "$cmd" "ost1"
14274         # read
14275         cancel_lru_locks osc
14276         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
14277         verify_jobstats "$cmd" "ost1"
14278         # truncate
14279         cmd="$TRUNCATE $DIR/$tfile 0"
14280         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14281         # rename
14282         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
14283         verify_jobstats "$cmd" "$SINGLEMDS"
14284         # jobstats expiry - sleep until old stats should be expired
14285         local left=$((new_interval + 5 - (SECONDS - start)))
14286         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
14287                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
14288                         "0" $left
14289         cmd="mkdir $DIR/$tdir.expire"
14290         verify_jobstats "$cmd" "$SINGLEMDS"
14291         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
14292             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
14293
14294         # Ensure that jobid are present in changelog (if supported by MDS)
14295         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
14296                 changelog_dump | tail -10
14297                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
14298                 [ $jobids -eq 9 ] ||
14299                         error "Wrong changelog jobid count $jobids != 9"
14300
14301                 # LU-5862
14302                 JOBENV="disable"
14303                 jobstats_set $JOBENV
14304                 touch $DIR/$tfile
14305                 changelog_dump | grep $tfile
14306                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
14307                 [ $jobids -eq 0 ] ||
14308                         error "Unexpected jobids when jobid_var=$JOBENV"
14309         fi
14310
14311         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
14312         JOBENV="JOBCOMPLEX"
14313         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
14314
14315         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
14316 }
14317 run_test 205 "Verify job stats"
14318
14319 # LU-1480, LU-1773 and LU-1657
14320 test_206() {
14321         mkdir -p $DIR/$tdir
14322         $LFS setstripe -c -1 $DIR/$tdir
14323 #define OBD_FAIL_LOV_INIT 0x1403
14324         $LCTL set_param fail_loc=0xa0001403
14325         $LCTL set_param fail_val=1
14326         touch $DIR/$tdir/$tfile || true
14327 }
14328 run_test 206 "fail lov_init_raid0() doesn't lbug"
14329
14330 test_207a() {
14331         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14332         local fsz=`stat -c %s $DIR/$tfile`
14333         cancel_lru_locks mdc
14334
14335         # do not return layout in getattr intent
14336 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
14337         $LCTL set_param fail_loc=0x170
14338         local sz=`stat -c %s $DIR/$tfile`
14339
14340         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
14341
14342         rm -rf $DIR/$tfile
14343 }
14344 run_test 207a "can refresh layout at glimpse"
14345
14346 test_207b() {
14347         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14348         local cksum=`md5sum $DIR/$tfile`
14349         local fsz=`stat -c %s $DIR/$tfile`
14350         cancel_lru_locks mdc
14351         cancel_lru_locks osc
14352
14353         # do not return layout in getattr intent
14354 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
14355         $LCTL set_param fail_loc=0x171
14356
14357         # it will refresh layout after the file is opened but before read issues
14358         echo checksum is "$cksum"
14359         echo "$cksum" |md5sum -c --quiet || error "file differs"
14360
14361         rm -rf $DIR/$tfile
14362 }
14363 run_test 207b "can refresh layout at open"
14364
14365 test_208() {
14366         # FIXME: in this test suite, only RD lease is used. This is okay
14367         # for now as only exclusive open is supported. After generic lease
14368         # is done, this test suite should be revised. - Jinshan
14369
14370         remote_mds_nodsh && skip "remote MDS with nodsh"
14371         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
14372                 skip "Need MDS version at least 2.4.52"
14373
14374         echo "==== test 1: verify get lease work"
14375         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
14376
14377         echo "==== test 2: verify lease can be broken by upcoming open"
14378         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14379         local PID=$!
14380         sleep 1
14381
14382         $MULTIOP $DIR/$tfile oO_RDONLY:c
14383         kill -USR1 $PID && wait $PID || error "break lease error"
14384
14385         echo "==== test 3: verify lease can't be granted if an open already exists"
14386         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
14387         local PID=$!
14388         sleep 1
14389
14390         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
14391         kill -USR1 $PID && wait $PID || error "open file error"
14392
14393         echo "==== test 4: lease can sustain over recovery"
14394         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
14395         PID=$!
14396         sleep 1
14397
14398         fail mds1
14399
14400         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
14401
14402         echo "==== test 5: lease broken can't be regained by replay"
14403         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14404         PID=$!
14405         sleep 1
14406
14407         # open file to break lease and then recovery
14408         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
14409         fail mds1
14410
14411         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
14412
14413         rm -f $DIR/$tfile
14414 }
14415 run_test 208 "Exclusive open"
14416
14417 test_209() {
14418         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
14419                 skip_env "must have disp_stripe"
14420
14421         touch $DIR/$tfile
14422         sync; sleep 5; sync;
14423
14424         echo 3 > /proc/sys/vm/drop_caches
14425         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14426
14427         # open/close 500 times
14428         for i in $(seq 500); do
14429                 cat $DIR/$tfile
14430         done
14431
14432         echo 3 > /proc/sys/vm/drop_caches
14433         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14434
14435         echo "before: $req_before, after: $req_after"
14436         [ $((req_after - req_before)) -ge 300 ] &&
14437                 error "open/close requests are not freed"
14438         return 0
14439 }
14440 run_test 209 "read-only open/close requests should be freed promptly"
14441
14442 test_212() {
14443         size=`date +%s`
14444         size=$((size % 8192 + 1))
14445         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
14446         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
14447         rm -f $DIR/f212 $DIR/f212.xyz
14448 }
14449 run_test 212 "Sendfile test ============================================"
14450
14451 test_213() {
14452         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
14453         cancel_lru_locks osc
14454         lctl set_param fail_loc=0x8000040f
14455         # generate a read lock
14456         cat $DIR/$tfile > /dev/null
14457         # write to the file, it will try to cancel the above read lock.
14458         cat /etc/hosts >> $DIR/$tfile
14459 }
14460 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
14461
14462 test_214() { # for bug 20133
14463         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
14464         for (( i=0; i < 340; i++ )) ; do
14465                 touch $DIR/$tdir/d214c/a$i
14466         done
14467
14468         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
14469         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
14470         ls $DIR/d214c || error "ls $DIR/d214c failed"
14471         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
14472         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
14473 }
14474 run_test 214 "hash-indexed directory test - bug 20133"
14475
14476 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
14477 create_lnet_proc_files() {
14478         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
14479 }
14480
14481 # counterpart of create_lnet_proc_files
14482 remove_lnet_proc_files() {
14483         rm -f $TMP/lnet_$1.sys
14484 }
14485
14486 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14487 # 3rd arg as regexp for body
14488 check_lnet_proc_stats() {
14489         local l=$(cat "$TMP/lnet_$1" |wc -l)
14490         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
14491
14492         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
14493 }
14494
14495 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14496 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
14497 # optional and can be regexp for 2nd line (lnet.routes case)
14498 check_lnet_proc_entry() {
14499         local blp=2          # blp stands for 'position of 1st line of body'
14500         [ -z "$5" ] || blp=3 # lnet.routes case
14501
14502         local l=$(cat "$TMP/lnet_$1" |wc -l)
14503         # subtracting one from $blp because the body can be empty
14504         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
14505
14506         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
14507                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
14508
14509         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
14510                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
14511
14512         # bail out if any unexpected line happened
14513         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
14514         [ "$?" != 0 ] || error "$2 misformatted"
14515 }
14516
14517 test_215() { # for bugs 18102, 21079, 21517
14518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14519
14520         local N='(0|[1-9][0-9]*)'       # non-negative numeric
14521         local P='[1-9][0-9]*'           # positive numeric
14522         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
14523         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
14524         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
14525         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
14526
14527         local L1 # regexp for 1st line
14528         local L2 # regexp for 2nd line (optional)
14529         local BR # regexp for the rest (body)
14530
14531         # lnet.stats should look as 11 space-separated non-negative numerics
14532         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
14533         create_lnet_proc_files "stats"
14534         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
14535         remove_lnet_proc_files "stats"
14536
14537         # lnet.routes should look like this:
14538         # Routing disabled/enabled
14539         # net hops priority state router
14540         # where net is a string like tcp0, hops > 0, priority >= 0,
14541         # state is up/down,
14542         # router is a string like 192.168.1.1@tcp2
14543         L1="^Routing (disabled|enabled)$"
14544         L2="^net +hops +priority +state +router$"
14545         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
14546         create_lnet_proc_files "routes"
14547         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
14548         remove_lnet_proc_files "routes"
14549
14550         # lnet.routers should look like this:
14551         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
14552         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
14553         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
14554         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
14555         L1="^ref +rtr_ref +alive_cnt +state +last_ping +ping_sent +deadline +down_ni +router$"
14556         BR="^$P +$P +$N +(up|down) +$N +(0|1) +$I +$I +$NID$"
14557         create_lnet_proc_files "routers"
14558         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
14559         remove_lnet_proc_files "routers"
14560
14561         # lnet.peers should look like this:
14562         # nid refs state last max rtr min tx min queue
14563         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
14564         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
14565         # numeric (0 or >0 or <0), queue >= 0.
14566         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
14567         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
14568         create_lnet_proc_files "peers"
14569         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
14570         remove_lnet_proc_files "peers"
14571
14572         # lnet.buffers  should look like this:
14573         # pages count credits min
14574         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
14575         L1="^pages +count +credits +min$"
14576         BR="^ +$N +$N +$I +$I$"
14577         create_lnet_proc_files "buffers"
14578         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
14579         remove_lnet_proc_files "buffers"
14580
14581         # lnet.nis should look like this:
14582         # nid status alive refs peer rtr max tx min
14583         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
14584         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
14585         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
14586         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
14587         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
14588         create_lnet_proc_files "nis"
14589         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
14590         remove_lnet_proc_files "nis"
14591
14592         # can we successfully write to lnet.stats?
14593         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
14594 }
14595 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
14596
14597 test_216() { # bug 20317
14598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14599         remote_ost_nodsh && skip "remote OST with nodsh"
14600
14601         local node
14602         local facets=$(get_facets OST)
14603         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14604
14605         save_lustre_params client "osc.*.contention_seconds" > $p
14606         save_lustre_params $facets \
14607                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
14608         save_lustre_params $facets \
14609                 "ldlm.namespaces.filter-*.contended_locks" >> $p
14610         save_lustre_params $facets \
14611                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
14612         clear_stats osc.*.osc_stats
14613
14614         # agressive lockless i/o settings
14615         do_nodes $(comma_list $(osts_nodes)) \
14616                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
14617                         ldlm.namespaces.filter-*.contended_locks=0 \
14618                         ldlm.namespaces.filter-*.contention_seconds=60"
14619         lctl set_param -n osc.*.contention_seconds=60
14620
14621         $DIRECTIO write $DIR/$tfile 0 10 4096
14622         $CHECKSTAT -s 40960 $DIR/$tfile
14623
14624         # disable lockless i/o
14625         do_nodes $(comma_list $(osts_nodes)) \
14626                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
14627                         ldlm.namespaces.filter-*.contended_locks=32 \
14628                         ldlm.namespaces.filter-*.contention_seconds=0"
14629         lctl set_param -n osc.*.contention_seconds=0
14630         clear_stats osc.*.osc_stats
14631
14632         dd if=/dev/zero of=$DIR/$tfile count=0
14633         $CHECKSTAT -s 0 $DIR/$tfile
14634
14635         restore_lustre_params <$p
14636         rm -f $p
14637         rm $DIR/$tfile
14638 }
14639 run_test 216 "check lockless direct write updates file size and kms correctly"
14640
14641 test_217() { # bug 22430
14642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14643
14644         local node
14645         local nid
14646
14647         for node in $(nodes_list); do
14648                 nid=$(host_nids_address $node $NETTYPE)
14649                 if [[ $nid = *-* ]] ; then
14650                         echo "lctl ping $(h2nettype $nid)"
14651                         lctl ping $(h2nettype $nid)
14652                 else
14653                         echo "skipping $node (no hyphen detected)"
14654                 fi
14655         done
14656 }
14657 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
14658
14659 test_218() {
14660        # do directio so as not to populate the page cache
14661        log "creating a 10 Mb file"
14662        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
14663        log "starting reads"
14664        dd if=$DIR/$tfile of=/dev/null bs=4096 &
14665        log "truncating the file"
14666        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
14667        log "killing dd"
14668        kill %+ || true # reads might have finished
14669        echo "wait until dd is finished"
14670        wait
14671        log "removing the temporary file"
14672        rm -rf $DIR/$tfile || error "tmp file removal failed"
14673 }
14674 run_test 218 "parallel read and truncate should not deadlock"
14675
14676 test_219() {
14677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14678
14679         # write one partial page
14680         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
14681         # set no grant so vvp_io_commit_write will do sync write
14682         $LCTL set_param fail_loc=0x411
14683         # write a full page at the end of file
14684         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
14685
14686         $LCTL set_param fail_loc=0
14687         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
14688         $LCTL set_param fail_loc=0x411
14689         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
14690
14691         # LU-4201
14692         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
14693         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
14694 }
14695 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
14696
14697 test_220() { #LU-325
14698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14699         remote_ost_nodsh && skip "remote OST with nodsh"
14700         remote_mds_nodsh && skip "remote MDS with nodsh"
14701         remote_mgs_nodsh && skip "remote MGS with nodsh"
14702
14703         local OSTIDX=0
14704
14705         # create on MDT0000 so the last_id and next_id are correct
14706         mkdir $DIR/$tdir
14707         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
14708         OST=${OST%_UUID}
14709
14710         # on the mdt's osc
14711         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
14712         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
14713                         osc.$mdtosc_proc1.prealloc_last_id)
14714         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
14715                         osc.$mdtosc_proc1.prealloc_next_id)
14716
14717         $LFS df -i
14718
14719         if ! combined_mgs_mds ; then
14720                 mount_mgs_client
14721         fi
14722
14723         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
14724         #define OBD_FAIL_OST_ENOINO              0x229
14725         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
14726         create_pool $FSNAME.$TESTNAME || return 1
14727         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
14728
14729         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
14730
14731         MDSOBJS=$((last_id - next_id))
14732         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
14733
14734         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
14735         echo "OST still has $count kbytes free"
14736
14737         echo "create $MDSOBJS files @next_id..."
14738         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
14739
14740         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
14741                         osc.$mdtosc_proc1.prealloc_last_id)
14742         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
14743                         osc.$mdtosc_proc1.prealloc_next_id)
14744
14745         echo "after creation, last_id=$last_id2, next_id=$next_id2"
14746         $LFS df -i
14747
14748         echo "cleanup..."
14749
14750         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
14751         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
14752
14753         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
14754                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
14755         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
14756                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
14757         echo "unlink $MDSOBJS files @$next_id..."
14758         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
14759
14760         if ! combined_mgs_mds ; then
14761                 umount_mgs_client
14762         fi
14763 }
14764 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
14765
14766 test_221() {
14767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14768
14769         dd if=`which date` of=$MOUNT/date oflag=sync
14770         chmod +x $MOUNT/date
14771
14772         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
14773         $LCTL set_param fail_loc=0x80001401
14774
14775         $MOUNT/date > /dev/null
14776         rm -f $MOUNT/date
14777 }
14778 run_test 221 "make sure fault and truncate race to not cause OOM"
14779
14780 test_222a () {
14781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14782
14783         rm -rf $DIR/$tdir
14784         test_mkdir $DIR/$tdir
14785         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14786         createmany -o $DIR/$tdir/$tfile 10
14787         cancel_lru_locks mdc
14788         cancel_lru_locks osc
14789         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
14790         $LCTL set_param fail_loc=0x31a
14791         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
14792         $LCTL set_param fail_loc=0
14793         rm -r $DIR/$tdir
14794 }
14795 run_test 222a "AGL for ls should not trigger CLIO lock failure"
14796
14797 test_222b () {
14798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14799
14800         rm -rf $DIR/$tdir
14801         test_mkdir $DIR/$tdir
14802         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14803         createmany -o $DIR/$tdir/$tfile 10
14804         cancel_lru_locks mdc
14805         cancel_lru_locks osc
14806         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
14807         $LCTL set_param fail_loc=0x31a
14808         rm -r $DIR/$tdir || error "AGL for rmdir failed"
14809         $LCTL set_param fail_loc=0
14810 }
14811 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
14812
14813 test_223 () {
14814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14815
14816         rm -rf $DIR/$tdir
14817         test_mkdir $DIR/$tdir
14818         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14819         createmany -o $DIR/$tdir/$tfile 10
14820         cancel_lru_locks mdc
14821         cancel_lru_locks osc
14822         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
14823         $LCTL set_param fail_loc=0x31b
14824         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
14825         $LCTL set_param fail_loc=0
14826         rm -r $DIR/$tdir
14827 }
14828 run_test 223 "osc reenqueue if without AGL lock granted ======================="
14829
14830 test_224a() { # LU-1039, MRP-303
14831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14832
14833         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
14834         $LCTL set_param fail_loc=0x508
14835         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
14836         $LCTL set_param fail_loc=0
14837         df $DIR
14838 }
14839 run_test 224a "Don't panic on bulk IO failure"
14840
14841 test_224b() { # LU-1039, MRP-303
14842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14843
14844         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
14845         cancel_lru_locks osc
14846         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
14847         $LCTL set_param fail_loc=0x515
14848         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
14849         $LCTL set_param fail_loc=0
14850         df $DIR
14851 }
14852 run_test 224b "Don't panic on bulk IO failure"
14853
14854 test_224c() { # LU-6441
14855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14856         remote_mds_nodsh && skip "remote MDS with nodsh"
14857
14858         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14859         save_writethrough $p
14860         set_cache writethrough on
14861
14862         local pages_per_rpc=$($LCTL get_param \
14863                                 osc.*.max_pages_per_rpc)
14864         local at_max=$($LCTL get_param -n at_max)
14865         local timeout=$($LCTL get_param -n timeout)
14866         local test_at="at_max"
14867         local param_at="$FSNAME.sys.at_max"
14868         local test_timeout="timeout"
14869         local param_timeout="$FSNAME.sys.timeout"
14870
14871         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
14872
14873         set_persistent_param_and_check client "$test_at" "$param_at" 0
14874         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
14875
14876         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
14877         do_facet ost1 "$LCTL set_param fail_loc=0x520"
14878         $LFS setstripe -c 1 -i 0 $DIR/$tfile
14879         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
14880         sync
14881         do_facet ost1 "$LCTL set_param fail_loc=0"
14882
14883         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
14884         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
14885                 $timeout
14886
14887         $LCTL set_param -n $pages_per_rpc
14888         restore_lustre_params < $p
14889         rm -f $p
14890 }
14891 run_test 224c "Don't hang if one of md lost during large bulk RPC"
14892
14893 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
14894 test_225a () {
14895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14896         if [ -z ${MDSSURVEY} ]; then
14897                 skip_env "mds-survey not found"
14898         fi
14899         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
14900                 skip "Need MDS version at least 2.2.51"
14901
14902         local mds=$(facet_host $SINGLEMDS)
14903         local target=$(do_nodes $mds 'lctl dl' |
14904                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
14905
14906         local cmd1="file_count=1000 thrhi=4"
14907         local cmd2="dir_count=2 layer=mdd stripe_count=0"
14908         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
14909         local cmd="$cmd1 $cmd2 $cmd3"
14910
14911         rm -f ${TMP}/mds_survey*
14912         echo + $cmd
14913         eval $cmd || error "mds-survey with zero-stripe failed"
14914         cat ${TMP}/mds_survey*
14915         rm -f ${TMP}/mds_survey*
14916 }
14917 run_test 225a "Metadata survey sanity with zero-stripe"
14918
14919 test_225b () {
14920         if [ -z ${MDSSURVEY} ]; then
14921                 skip_env "mds-survey not found"
14922         fi
14923         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
14924                 skip "Need MDS version at least 2.2.51"
14925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14926         remote_mds_nodsh && skip "remote MDS with nodsh"
14927         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
14928                 skip_env "Need to mount OST to test"
14929         fi
14930
14931         local mds=$(facet_host $SINGLEMDS)
14932         local target=$(do_nodes $mds 'lctl dl' |
14933                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
14934
14935         local cmd1="file_count=1000 thrhi=4"
14936         local cmd2="dir_count=2 layer=mdd stripe_count=1"
14937         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
14938         local cmd="$cmd1 $cmd2 $cmd3"
14939
14940         rm -f ${TMP}/mds_survey*
14941         echo + $cmd
14942         eval $cmd || error "mds-survey with stripe_count failed"
14943         cat ${TMP}/mds_survey*
14944         rm -f ${TMP}/mds_survey*
14945 }
14946 run_test 225b "Metadata survey sanity with stripe_count = 1"
14947
14948 mcreate_path2fid () {
14949         local mode=$1
14950         local major=$2
14951         local minor=$3
14952         local name=$4
14953         local desc=$5
14954         local path=$DIR/$tdir/$name
14955         local fid
14956         local rc
14957         local fid_path
14958
14959         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
14960                 error "cannot create $desc"
14961
14962         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
14963         rc=$?
14964         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
14965
14966         fid_path=$($LFS fid2path $MOUNT $fid)
14967         rc=$?
14968         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
14969
14970         [ "$path" == "$fid_path" ] ||
14971                 error "fid2path returned $fid_path, expected $path"
14972
14973         echo "pass with $path and $fid"
14974 }
14975
14976 test_226a () {
14977         rm -rf $DIR/$tdir
14978         mkdir -p $DIR/$tdir
14979
14980         mcreate_path2fid 0010666 0 0 fifo "FIFO"
14981         mcreate_path2fid 0020666 1 3 null "character special file (null)"
14982         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
14983         mcreate_path2fid 0040666 0 0 dir "directory"
14984         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
14985         mcreate_path2fid 0100666 0 0 file "regular file"
14986         mcreate_path2fid 0120666 0 0 link "symbolic link"
14987         mcreate_path2fid 0140666 0 0 sock "socket"
14988 }
14989 run_test 226a "call path2fid and fid2path on files of all type"
14990
14991 test_226b () {
14992         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14993
14994         local MDTIDX=1
14995
14996         rm -rf $DIR/$tdir
14997         mkdir -p $DIR/$tdir
14998         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
14999                 error "create remote directory failed"
15000         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
15001         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
15002                                 "character special file (null)"
15003         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
15004                                 "character special file (no device)"
15005         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
15006         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
15007                                 "block special file (loop)"
15008         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
15009         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
15010         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
15011 }
15012 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
15013
15014 # LU-1299 Executing or running ldd on a truncated executable does not
15015 # cause an out-of-memory condition.
15016 test_227() {
15017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15018         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
15019
15020         dd if=$(which date) of=$MOUNT/date bs=1k count=1
15021         chmod +x $MOUNT/date
15022
15023         $MOUNT/date > /dev/null
15024         ldd $MOUNT/date > /dev/null
15025         rm -f $MOUNT/date
15026 }
15027 run_test 227 "running truncated executable does not cause OOM"
15028
15029 # LU-1512 try to reuse idle OI blocks
15030 test_228a() {
15031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15032         remote_mds_nodsh && skip "remote MDS with nodsh"
15033         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15034
15035         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15036         local myDIR=$DIR/$tdir
15037
15038         mkdir -p $myDIR
15039         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15040         $LCTL set_param fail_loc=0x80001002
15041         createmany -o $myDIR/t- 10000
15042         $LCTL set_param fail_loc=0
15043         # The guard is current the largest FID holder
15044         touch $myDIR/guard
15045         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15046                     tr -d '[')
15047         local IDX=$(($SEQ % 64))
15048
15049         do_facet $SINGLEMDS sync
15050         # Make sure journal flushed.
15051         sleep 6
15052         local blk1=$(do_facet $SINGLEMDS \
15053                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15054                      grep Blockcount | awk '{print $4}')
15055
15056         # Remove old files, some OI blocks will become idle.
15057         unlinkmany $myDIR/t- 10000
15058         # Create new files, idle OI blocks should be reused.
15059         createmany -o $myDIR/t- 2000
15060         do_facet $SINGLEMDS sync
15061         # Make sure journal flushed.
15062         sleep 6
15063         local blk2=$(do_facet $SINGLEMDS \
15064                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15065                      grep Blockcount | awk '{print $4}')
15066
15067         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15068 }
15069 run_test 228a "try to reuse idle OI blocks"
15070
15071 test_228b() {
15072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15073         remote_mds_nodsh && skip "remote MDS with nodsh"
15074         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15075
15076         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15077         local myDIR=$DIR/$tdir
15078
15079         mkdir -p $myDIR
15080         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15081         $LCTL set_param fail_loc=0x80001002
15082         createmany -o $myDIR/t- 10000
15083         $LCTL set_param fail_loc=0
15084         # The guard is current the largest FID holder
15085         touch $myDIR/guard
15086         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15087                     tr -d '[')
15088         local IDX=$(($SEQ % 64))
15089
15090         do_facet $SINGLEMDS sync
15091         # Make sure journal flushed.
15092         sleep 6
15093         local blk1=$(do_facet $SINGLEMDS \
15094                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15095                      grep Blockcount | awk '{print $4}')
15096
15097         # Remove old files, some OI blocks will become idle.
15098         unlinkmany $myDIR/t- 10000
15099
15100         # stop the MDT
15101         stop $SINGLEMDS || error "Fail to stop MDT."
15102         # remount the MDT
15103         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
15104
15105         df $MOUNT || error "Fail to df."
15106         # Create new files, idle OI blocks should be reused.
15107         createmany -o $myDIR/t- 2000
15108         do_facet $SINGLEMDS sync
15109         # Make sure journal flushed.
15110         sleep 6
15111         local blk2=$(do_facet $SINGLEMDS \
15112                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15113                      grep Blockcount | awk '{print $4}')
15114
15115         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15116 }
15117 run_test 228b "idle OI blocks can be reused after MDT restart"
15118
15119 #LU-1881
15120 test_228c() {
15121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15122         remote_mds_nodsh && skip "remote MDS with nodsh"
15123         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15124
15125         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15126         local myDIR=$DIR/$tdir
15127
15128         mkdir -p $myDIR
15129         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15130         $LCTL set_param fail_loc=0x80001002
15131         # 20000 files can guarantee there are index nodes in the OI file
15132         createmany -o $myDIR/t- 20000
15133         $LCTL set_param fail_loc=0
15134         # The guard is current the largest FID holder
15135         touch $myDIR/guard
15136         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15137                     tr -d '[')
15138         local IDX=$(($SEQ % 64))
15139
15140         do_facet $SINGLEMDS sync
15141         # Make sure journal flushed.
15142         sleep 6
15143         local blk1=$(do_facet $SINGLEMDS \
15144                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15145                      grep Blockcount | awk '{print $4}')
15146
15147         # Remove old files, some OI blocks will become idle.
15148         unlinkmany $myDIR/t- 20000
15149         rm -f $myDIR/guard
15150         # The OI file should become empty now
15151
15152         # Create new files, idle OI blocks should be reused.
15153         createmany -o $myDIR/t- 2000
15154         do_facet $SINGLEMDS sync
15155         # Make sure journal flushed.
15156         sleep 6
15157         local blk2=$(do_facet $SINGLEMDS \
15158                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15159                      grep Blockcount | awk '{print $4}')
15160
15161         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15162 }
15163 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
15164
15165 test_229() { # LU-2482, LU-3448
15166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15167         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
15168         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
15169                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
15170
15171         rm -f $DIR/$tfile
15172
15173         # Create a file with a released layout and stripe count 2.
15174         $MULTIOP $DIR/$tfile H2c ||
15175                 error "failed to create file with released layout"
15176
15177         $LFS getstripe -v $DIR/$tfile
15178
15179         local pattern=$($LFS getstripe -L $DIR/$tfile)
15180         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
15181
15182         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
15183                 error "getstripe"
15184         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
15185         stat $DIR/$tfile || error "failed to stat released file"
15186
15187         chown $RUNAS_ID $DIR/$tfile ||
15188                 error "chown $RUNAS_ID $DIR/$tfile failed"
15189
15190         chgrp $RUNAS_ID $DIR/$tfile ||
15191                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
15192
15193         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
15194         rm $DIR/$tfile || error "failed to remove released file"
15195 }
15196 run_test 229 "getstripe/stat/rm/attr changes work on released files"
15197
15198 test_230a() {
15199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15200         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15201         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15202                 skip "Need MDS version at least 2.11.52"
15203
15204         local MDTIDX=1
15205
15206         test_mkdir $DIR/$tdir
15207         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
15208         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
15209         [ $mdt_idx -ne 0 ] &&
15210                 error "create local directory on wrong MDT $mdt_idx"
15211
15212         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
15213                         error "create remote directory failed"
15214         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
15215         [ $mdt_idx -ne $MDTIDX ] &&
15216                 error "create remote directory on wrong MDT $mdt_idx"
15217
15218         createmany -o $DIR/$tdir/test_230/t- 10 ||
15219                 error "create files on remote directory failed"
15220         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
15221         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
15222         rm -r $DIR/$tdir || error "unlink remote directory failed"
15223 }
15224 run_test 230a "Create remote directory and files under the remote directory"
15225
15226 test_230b() {
15227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15228         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15229         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15230                 skip "Need MDS version at least 2.11.52"
15231
15232         local MDTIDX=1
15233         local mdt_index
15234         local i
15235         local file
15236         local pid
15237         local stripe_count
15238         local migrate_dir=$DIR/$tdir/migrate_dir
15239         local other_dir=$DIR/$tdir/other_dir
15240
15241         test_mkdir $DIR/$tdir
15242         test_mkdir -i0 -c1 $migrate_dir
15243         test_mkdir -i0 -c1 $other_dir
15244         for ((i=0; i<10; i++)); do
15245                 mkdir -p $migrate_dir/dir_${i}
15246                 createmany -o $migrate_dir/dir_${i}/f 10 ||
15247                         error "create files under remote dir failed $i"
15248         done
15249
15250         cp /etc/passwd $migrate_dir/$tfile
15251         cp /etc/passwd $other_dir/$tfile
15252         chattr +SAD $migrate_dir
15253         chattr +SAD $migrate_dir/$tfile
15254
15255         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15256         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15257         local old_dir_mode=$(stat -c%f $migrate_dir)
15258         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
15259
15260         mkdir -p $migrate_dir/dir_default_stripe2
15261         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
15262         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
15263
15264         mkdir -p $other_dir
15265         ln $migrate_dir/$tfile $other_dir/luna
15266         ln $migrate_dir/$tfile $migrate_dir/sofia
15267         ln $other_dir/$tfile $migrate_dir/david
15268         ln -s $migrate_dir/$tfile $other_dir/zachary
15269         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
15270         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
15271
15272         $LFS migrate -m $MDTIDX $migrate_dir ||
15273                 error "fails on migrating remote dir to MDT1"
15274
15275         echo "migratate to MDT1, then checking.."
15276         for ((i = 0; i < 10; i++)); do
15277                 for file in $(find $migrate_dir/dir_${i}); do
15278                         mdt_index=$($LFS getstripe -m $file)
15279                         [ $mdt_index == $MDTIDX ] ||
15280                                 error "$file is not on MDT${MDTIDX}"
15281                 done
15282         done
15283
15284         # the multiple link file should still in MDT0
15285         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
15286         [ $mdt_index == 0 ] ||
15287                 error "$file is not on MDT${MDTIDX}"
15288
15289         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15290         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15291                 error " expect $old_dir_flag get $new_dir_flag"
15292
15293         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15294         [ "$old_file_flag" = "$new_file_flag" ] ||
15295                 error " expect $old_file_flag get $new_file_flag"
15296
15297         local new_dir_mode=$(stat -c%f $migrate_dir)
15298         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15299                 error "expect mode $old_dir_mode get $new_dir_mode"
15300
15301         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15302         [ "$old_file_mode" = "$new_file_mode" ] ||
15303                 error "expect mode $old_file_mode get $new_file_mode"
15304
15305         diff /etc/passwd $migrate_dir/$tfile ||
15306                 error "$tfile different after migration"
15307
15308         diff /etc/passwd $other_dir/luna ||
15309                 error "luna different after migration"
15310
15311         diff /etc/passwd $migrate_dir/sofia ||
15312                 error "sofia different after migration"
15313
15314         diff /etc/passwd $migrate_dir/david ||
15315                 error "david different after migration"
15316
15317         diff /etc/passwd $other_dir/zachary ||
15318                 error "zachary different after migration"
15319
15320         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15321                 error "${tfile}_ln different after migration"
15322
15323         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15324                 error "${tfile}_ln_other different after migration"
15325
15326         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
15327         [ $stripe_count = 2 ] ||
15328                 error "dir strpe_count $d != 2 after migration."
15329
15330         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
15331         [ $stripe_count = 2 ] ||
15332                 error "file strpe_count $d != 2 after migration."
15333
15334         #migrate back to MDT0
15335         MDTIDX=0
15336
15337         $LFS migrate -m $MDTIDX $migrate_dir ||
15338                 error "fails on migrating remote dir to MDT0"
15339
15340         echo "migrate back to MDT0, checking.."
15341         for file in $(find $migrate_dir); do
15342                 mdt_index=$($LFS getstripe -m $file)
15343                 [ $mdt_index == $MDTIDX ] ||
15344                         error "$file is not on MDT${MDTIDX}"
15345         done
15346
15347         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15348         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15349                 error " expect $old_dir_flag get $new_dir_flag"
15350
15351         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15352         [ "$old_file_flag" = "$new_file_flag" ] ||
15353                 error " expect $old_file_flag get $new_file_flag"
15354
15355         local new_dir_mode=$(stat -c%f $migrate_dir)
15356         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15357                 error "expect mode $old_dir_mode get $new_dir_mode"
15358
15359         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15360         [ "$old_file_mode" = "$new_file_mode" ] ||
15361                 error "expect mode $old_file_mode get $new_file_mode"
15362
15363         diff /etc/passwd ${migrate_dir}/$tfile ||
15364                 error "$tfile different after migration"
15365
15366         diff /etc/passwd ${other_dir}/luna ||
15367                 error "luna different after migration"
15368
15369         diff /etc/passwd ${migrate_dir}/sofia ||
15370                 error "sofia different after migration"
15371
15372         diff /etc/passwd ${other_dir}/zachary ||
15373                 error "zachary different after migration"
15374
15375         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15376                 error "${tfile}_ln different after migration"
15377
15378         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15379                 error "${tfile}_ln_other different after migration"
15380
15381         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
15382         [ $stripe_count = 2 ] ||
15383                 error "dir strpe_count $d != 2 after migration."
15384
15385         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
15386         [ $stripe_count = 2 ] ||
15387                 error "file strpe_count $d != 2 after migration."
15388
15389         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15390 }
15391 run_test 230b "migrate directory"
15392
15393 test_230c() {
15394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15395         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15396         remote_mds_nodsh && skip "remote MDS with nodsh"
15397         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15398                 skip "Need MDS version at least 2.11.52"
15399
15400         local MDTIDX=1
15401         local total=3
15402         local mdt_index
15403         local file
15404         local migrate_dir=$DIR/$tdir/migrate_dir
15405
15406         #If migrating directory fails in the middle, all entries of
15407         #the directory is still accessiable.
15408         test_mkdir $DIR/$tdir
15409         test_mkdir -i0 -c1 $migrate_dir
15410         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
15411         stat $migrate_dir
15412         createmany -o $migrate_dir/f $total ||
15413                 error "create files under ${migrate_dir} failed"
15414
15415         # fail after migrating top dir, and this will fail only once, so the
15416         # first sub file migration will fail (currently f3), others succeed.
15417         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
15418         do_facet mds1 lctl set_param fail_loc=0x1801
15419         local t=$(ls $migrate_dir | wc -l)
15420         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
15421                 error "migrate should fail"
15422         local u=$(ls $migrate_dir | wc -l)
15423         [ "$u" == "$t" ] || error "$u != $t during migration"
15424
15425         # add new dir/file should succeed
15426         mkdir $migrate_dir/dir ||
15427                 error "mkdir failed under migrating directory"
15428         touch $migrate_dir/file ||
15429                 error "create file failed under migrating directory"
15430
15431         # add file with existing name should fail
15432         for file in $migrate_dir/f*; do
15433                 stat $file > /dev/null || error "stat $file failed"
15434                 $OPENFILE -f O_CREAT:O_EXCL $file &&
15435                         error "open(O_CREAT|O_EXCL) $file should fail"
15436                 $MULTIOP $file m && error "create $file should fail"
15437                 touch $DIR/$tdir/remote_dir/$tfile ||
15438                         error "touch $tfile failed"
15439                 ln $DIR/$tdir/remote_dir/$tfile $file &&
15440                         error "link $file should fail"
15441                 mdt_index=$($LFS getstripe -m $file)
15442                 if [ $mdt_index == 0 ]; then
15443                         # file failed to migrate is not allowed to rename to
15444                         mv $DIR/$tdir/remote_dir/$tfile $file &&
15445                                 error "rename to $file should fail"
15446                 else
15447                         mv $DIR/$tdir/remote_dir/$tfile $file ||
15448                                 error "rename to $file failed"
15449                 fi
15450                 echo hello >> $file || error "write $file failed"
15451         done
15452
15453         # resume migration with different options should fail
15454         $LFS migrate -m 0 $migrate_dir &&
15455                 error "migrate -m 0 $migrate_dir should fail"
15456
15457         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
15458                 error "migrate -c 2 $migrate_dir should fail"
15459
15460         # resume migration should succeed
15461         $LFS migrate -m $MDTIDX $migrate_dir ||
15462                 error "migrate $migrate_dir failed"
15463
15464         echo "Finish migration, then checking.."
15465         for file in $(find $migrate_dir); do
15466                 mdt_index=$($LFS getstripe -m $file)
15467                 [ $mdt_index == $MDTIDX ] ||
15468                         error "$file is not on MDT${MDTIDX}"
15469         done
15470
15471         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15472 }
15473 run_test 230c "check directory accessiblity if migration failed"
15474
15475 test_230d() {
15476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15477         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15478         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15479                 skip "Need MDS version at least 2.11.52"
15480         # LU-11235
15481         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
15482
15483         local migrate_dir=$DIR/$tdir/migrate_dir
15484         local old_index
15485         local new_index
15486         local old_count
15487         local new_count
15488         local new_hash
15489         local mdt_index
15490         local i
15491         local j
15492
15493         old_index=$((RANDOM % MDSCOUNT))
15494         old_count=$((MDSCOUNT - old_index))
15495         new_index=$((RANDOM % MDSCOUNT))
15496         new_count=$((MDSCOUNT - new_index))
15497         new_hash="all_char"
15498
15499         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
15500         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
15501
15502         test_mkdir $DIR/$tdir
15503         test_mkdir -i $old_index -c $old_count $migrate_dir
15504
15505         for ((i=0; i<100; i++)); do
15506                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
15507                 createmany -o $migrate_dir/dir_${i}/f 100 ||
15508                         error "create files under remote dir failed $i"
15509         done
15510
15511         echo -n "Migrate from MDT$old_index "
15512         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
15513         echo -n "to MDT$new_index"
15514         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
15515         echo
15516
15517         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
15518         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
15519                 error "migrate remote dir error"
15520
15521         echo "Finish migration, then checking.."
15522         for file in $(find $migrate_dir); do
15523                 mdt_index=$($LFS getstripe -m $file)
15524                 if [ $mdt_index -lt $new_index ] ||
15525                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
15526                         error "$file is on MDT$mdt_index"
15527                 fi
15528         done
15529
15530         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15531 }
15532 run_test 230d "check migrate big directory"
15533
15534 test_230e() {
15535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15536         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15537         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15538                 skip "Need MDS version at least 2.11.52"
15539
15540         local i
15541         local j
15542         local a_fid
15543         local b_fid
15544
15545         mkdir -p $DIR/$tdir
15546         mkdir $DIR/$tdir/migrate_dir
15547         mkdir $DIR/$tdir/other_dir
15548         touch $DIR/$tdir/migrate_dir/a
15549         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
15550         ls $DIR/$tdir/other_dir
15551
15552         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15553                 error "migrate dir fails"
15554
15555         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
15556         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
15557
15558         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15559         [ $mdt_index == 0 ] || error "a is not on MDT0"
15560
15561         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
15562                 error "migrate dir fails"
15563
15564         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
15565         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
15566
15567         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15568         [ $mdt_index == 1 ] || error "a is not on MDT1"
15569
15570         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
15571         [ $mdt_index == 1 ] || error "b is not on MDT1"
15572
15573         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
15574         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
15575
15576         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
15577
15578         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15579 }
15580 run_test 230e "migrate mulitple local link files"
15581
15582 test_230f() {
15583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15584         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15585         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15586                 skip "Need MDS version at least 2.11.52"
15587
15588         local a_fid
15589         local ln_fid
15590
15591         mkdir -p $DIR/$tdir
15592         mkdir $DIR/$tdir/migrate_dir
15593         $LFS mkdir -i1 $DIR/$tdir/other_dir
15594         touch $DIR/$tdir/migrate_dir/a
15595         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
15596         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
15597         ls $DIR/$tdir/other_dir
15598
15599         # a should be migrated to MDT1, since no other links on MDT0
15600         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15601                 error "#1 migrate dir fails"
15602         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
15603         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
15604         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15605         [ $mdt_index == 1 ] || error "a is not on MDT1"
15606
15607         # a should stay on MDT1, because it is a mulitple link file
15608         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
15609                 error "#2 migrate dir fails"
15610         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15611         [ $mdt_index == 1 ] || error "a is not on MDT1"
15612
15613         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15614                 error "#3 migrate dir fails"
15615
15616         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
15617         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
15618         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
15619
15620         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
15621         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
15622
15623         # a should be migrated to MDT0, since no other links on MDT1
15624         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
15625                 error "#4 migrate dir fails"
15626         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15627         [ $mdt_index == 0 ] || error "a is not on MDT0"
15628
15629         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15630 }
15631 run_test 230f "migrate mulitple remote link files"
15632
15633 test_230g() {
15634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15635         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15636         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15637                 skip "Need MDS version at least 2.11.52"
15638
15639         mkdir -p $DIR/$tdir/migrate_dir
15640
15641         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
15642                 error "migrating dir to non-exist MDT succeeds"
15643         true
15644 }
15645 run_test 230g "migrate dir to non-exist MDT"
15646
15647 test_230h() {
15648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15649         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15650         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15651                 skip "Need MDS version at least 2.11.52"
15652
15653         local mdt_index
15654
15655         mkdir -p $DIR/$tdir/migrate_dir
15656
15657         $LFS migrate -m1 $DIR &&
15658                 error "migrating mountpoint1 should fail"
15659
15660         $LFS migrate -m1 $DIR/$tdir/.. &&
15661                 error "migrating mountpoint2 should fail"
15662
15663         # same as mv
15664         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
15665                 error "migrating $tdir/migrate_dir/.. should fail"
15666
15667         true
15668 }
15669 run_test 230h "migrate .. and root"
15670
15671 test_230i() {
15672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15673         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15674         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15675                 skip "Need MDS version at least 2.11.52"
15676
15677         mkdir -p $DIR/$tdir/migrate_dir
15678
15679         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
15680                 error "migration fails with a tailing slash"
15681
15682         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
15683                 error "migration fails with two tailing slashes"
15684 }
15685 run_test 230i "lfs migrate -m tolerates trailing slashes"
15686
15687 test_230j() {
15688         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
15689         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15690                 skip "Need MDS version at least 2.11.52"
15691
15692         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
15693         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
15694                 error "create $tfile failed"
15695         cat /etc/passwd > $DIR/$tdir/$tfile
15696
15697         $LFS migrate -m 1 $DIR/$tdir
15698
15699         cmp /etc/passwd $DIR/$tdir/$tfile ||
15700                 error "DoM file mismatch after migration"
15701 }
15702 run_test 230j "DoM file data not changed after dir migration"
15703
15704 test_230k() {
15705         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
15706         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
15707                 skip "Need MDS version at least 2.11.56"
15708
15709         local total=20
15710         local files_on_starting_mdt=0
15711
15712         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
15713         $LFS getdirstripe $DIR/$tdir
15714         for i in $(seq $total); do
15715                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
15716                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
15717                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15718         done
15719
15720         echo "$files_on_starting_mdt files on MDT0"
15721
15722         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
15723         $LFS getdirstripe $DIR/$tdir
15724
15725         files_on_starting_mdt=0
15726         for i in $(seq $total); do
15727                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
15728                         error "file $tfile.$i mismatch after migration"
15729                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
15730                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15731         done
15732
15733         echo "$files_on_starting_mdt files on MDT1 after migration"
15734         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
15735
15736         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
15737         $LFS getdirstripe $DIR/$tdir
15738
15739         files_on_starting_mdt=0
15740         for i in $(seq $total); do
15741                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
15742                         error "file $tfile.$i mismatch after 2nd migration"
15743                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
15744                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15745         done
15746
15747         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
15748         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
15749
15750         true
15751 }
15752 run_test 230k "file data not changed after dir migration"
15753
15754 test_230l() {
15755         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
15756         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
15757                 skip "Need MDS version at least 2.11.56"
15758
15759         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
15760         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
15761                 error "create files under remote dir failed $i"
15762         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
15763 }
15764 run_test 230l "readdir between MDTs won't crash"
15765
15766 test_231a()
15767 {
15768         # For simplicity this test assumes that max_pages_per_rpc
15769         # is the same across all OSCs
15770         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
15771         local bulk_size=$((max_pages * PAGE_SIZE))
15772         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
15773                                        head -n 1)
15774
15775         mkdir -p $DIR/$tdir
15776         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
15777                 error "failed to set stripe with -S ${brw_size}M option"
15778
15779         # clear the OSC stats
15780         $LCTL set_param osc.*.stats=0 &>/dev/null
15781         stop_writeback
15782
15783         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
15784         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
15785                 oflag=direct &>/dev/null || error "dd failed"
15786
15787         sync; sleep 1; sync # just to be safe
15788         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
15789         if [ x$nrpcs != "x1" ]; then
15790                 $LCTL get_param osc.*.stats
15791                 error "found $nrpcs ost_write RPCs, not 1 as expected"
15792         fi
15793
15794         start_writeback
15795         # Drop the OSC cache, otherwise we will read from it
15796         cancel_lru_locks osc
15797
15798         # clear the OSC stats
15799         $LCTL set_param osc.*.stats=0 &>/dev/null
15800
15801         # Client reads $bulk_size.
15802         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
15803                 iflag=direct &>/dev/null || error "dd failed"
15804
15805         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
15806         if [ x$nrpcs != "x1" ]; then
15807                 $LCTL get_param osc.*.stats
15808                 error "found $nrpcs ost_read RPCs, not 1 as expected"
15809         fi
15810 }
15811 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
15812
15813 test_231b() {
15814         mkdir -p $DIR/$tdir
15815         local i
15816         for i in {0..1023}; do
15817                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
15818                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
15819                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
15820         done
15821         sync
15822 }
15823 run_test 231b "must not assert on fully utilized OST request buffer"
15824
15825 test_232a() {
15826         mkdir -p $DIR/$tdir
15827         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
15828
15829         #define OBD_FAIL_LDLM_OST_LVB            0x31c
15830         do_facet ost1 $LCTL set_param fail_loc=0x31c
15831
15832         # ignore dd failure
15833         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
15834
15835         do_facet ost1 $LCTL set_param fail_loc=0
15836         umount_client $MOUNT || error "umount failed"
15837         mount_client $MOUNT || error "mount failed"
15838         stop ost1 || error "cannot stop ost1"
15839         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
15840 }
15841 run_test 232a "failed lock should not block umount"
15842
15843 test_232b() {
15844         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
15845                 skip "Need MDS version at least 2.10.58"
15846
15847         mkdir -p $DIR/$tdir
15848         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
15849         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
15850         sync
15851         cancel_lru_locks osc
15852
15853         #define OBD_FAIL_LDLM_OST_LVB            0x31c
15854         do_facet ost1 $LCTL set_param fail_loc=0x31c
15855
15856         # ignore failure
15857         $LFS data_version $DIR/$tdir/$tfile || true
15858
15859         do_facet ost1 $LCTL set_param fail_loc=0
15860         umount_client $MOUNT || error "umount failed"
15861         mount_client $MOUNT || error "mount failed"
15862         stop ost1 || error "cannot stop ost1"
15863         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
15864 }
15865 run_test 232b "failed data version lock should not block umount"
15866
15867 test_233a() {
15868         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
15869                 skip "Need MDS version at least 2.3.64"
15870         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
15871
15872         local fid=$($LFS path2fid $MOUNT)
15873
15874         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15875                 error "cannot access $MOUNT using its FID '$fid'"
15876 }
15877 run_test 233a "checking that OBF of the FS root succeeds"
15878
15879 test_233b() {
15880         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
15881                 skip "Need MDS version at least 2.5.90"
15882         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
15883
15884         local fid=$($LFS path2fid $MOUNT/.lustre)
15885
15886         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15887                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
15888
15889         fid=$($LFS path2fid $MOUNT/.lustre/fid)
15890         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15891                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
15892 }
15893 run_test 233b "checking that OBF of the FS .lustre succeeds"
15894
15895 test_234() {
15896         local p="$TMP/sanityN-$TESTNAME.parameters"
15897         save_lustre_params client "llite.*.xattr_cache" > $p
15898         lctl set_param llite.*.xattr_cache 1 ||
15899                 skip_env "xattr cache is not supported"
15900
15901         mkdir -p $DIR/$tdir || error "mkdir failed"
15902         touch $DIR/$tdir/$tfile || error "touch failed"
15903         # OBD_FAIL_LLITE_XATTR_ENOMEM
15904         $LCTL set_param fail_loc=0x1405
15905         getfattr -n user.attr $DIR/$tdir/$tfile &&
15906                 error "getfattr should have failed with ENOMEM"
15907         $LCTL set_param fail_loc=0x0
15908         rm -rf $DIR/$tdir
15909
15910         restore_lustre_params < $p
15911         rm -f $p
15912 }
15913 run_test 234 "xattr cache should not crash on ENOMEM"
15914
15915 test_235() {
15916         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
15917                 skip "Need MDS version at least 2.4.52"
15918
15919         flock_deadlock $DIR/$tfile
15920         local RC=$?
15921         case $RC in
15922                 0)
15923                 ;;
15924                 124) error "process hangs on a deadlock"
15925                 ;;
15926                 *) error "error executing flock_deadlock $DIR/$tfile"
15927                 ;;
15928         esac
15929 }
15930 run_test 235 "LU-1715: flock deadlock detection does not work properly"
15931
15932 #LU-2935
15933 test_236() {
15934         check_swap_layouts_support
15935
15936         local ref1=/etc/passwd
15937         local ref2=/etc/group
15938         local file1=$DIR/$tdir/f1
15939         local file2=$DIR/$tdir/f2
15940
15941         test_mkdir -c1 $DIR/$tdir
15942         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
15943         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
15944         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
15945         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
15946         local fd=$(free_fd)
15947         local cmd="exec $fd<>$file2"
15948         eval $cmd
15949         rm $file2
15950         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
15951                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
15952         cmd="exec $fd>&-"
15953         eval $cmd
15954         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
15955
15956         #cleanup
15957         rm -rf $DIR/$tdir
15958 }
15959 run_test 236 "Layout swap on open unlinked file"
15960
15961 # LU-4659 linkea consistency
15962 test_238() {
15963         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15964                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15965                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15966                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15967
15968         touch $DIR/$tfile
15969         ln $DIR/$tfile $DIR/$tfile.lnk
15970         touch $DIR/$tfile.new
15971         mv $DIR/$tfile.new $DIR/$tfile
15972         local fid1=$($LFS path2fid $DIR/$tfile)
15973         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
15974         local path1=$($LFS fid2path $FSNAME "$fid1")
15975         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
15976         local path2=$($LFS fid2path $FSNAME "$fid2")
15977         [ $tfile.lnk == $path2 ] ||
15978                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
15979         rm -f $DIR/$tfile*
15980 }
15981 run_test 238 "Verify linkea consistency"
15982
15983 test_239A() { # was test_239
15984         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
15985                 skip "Need MDS version at least 2.5.60"
15986
15987         local list=$(comma_list $(mdts_nodes))
15988
15989         mkdir -p $DIR/$tdir
15990         createmany -o $DIR/$tdir/f- 5000
15991         unlinkmany $DIR/$tdir/f- 5000
15992         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
15993                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
15994         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
15995                         osp.*MDT*.sync_in_flight" | calc_sum)
15996         [ "$changes" -eq 0 ] || error "$changes not synced"
15997 }
15998 run_test 239A "osp_sync test"
15999
16000 test_239a() { #LU-5297
16001         remote_mds_nodsh && skip "remote MDS with nodsh"
16002
16003         touch $DIR/$tfile
16004         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
16005         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
16006         chgrp $RUNAS_GID $DIR/$tfile
16007         wait_delete_completed
16008 }
16009 run_test 239a "process invalid osp sync record correctly"
16010
16011 test_239b() { #LU-5297
16012         remote_mds_nodsh && skip "remote MDS with nodsh"
16013
16014         touch $DIR/$tfile1
16015         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
16016         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
16017         chgrp $RUNAS_GID $DIR/$tfile1
16018         wait_delete_completed
16019         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16020         touch $DIR/$tfile2
16021         chgrp $RUNAS_GID $DIR/$tfile2
16022         wait_delete_completed
16023 }
16024 run_test 239b "process osp sync record with ENOMEM error correctly"
16025
16026 test_240() {
16027         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16028         remote_mds_nodsh && skip "remote MDS with nodsh"
16029
16030         mkdir -p $DIR/$tdir
16031
16032         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
16033                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
16034         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
16035                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
16036
16037         umount_client $MOUNT || error "umount failed"
16038         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
16039         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
16040         mount_client $MOUNT || error "failed to mount client"
16041
16042         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
16043         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
16044 }
16045 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
16046
16047 test_241_bio() {
16048         local count=$1
16049         local bsize=$2
16050
16051         for LOOP in $(seq $count); do
16052                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
16053                 cancel_lru_locks $OSC || true
16054         done
16055 }
16056
16057 test_241_dio() {
16058         local count=$1
16059         local bsize=$2
16060
16061         for LOOP in $(seq $1); do
16062                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
16063                         2>/dev/null
16064         done
16065 }
16066
16067 test_241a() { # was test_241
16068         local bsize=$PAGE_SIZE
16069
16070         (( bsize < 40960 )) && bsize=40960
16071         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16072         ls -la $DIR/$tfile
16073         cancel_lru_locks $OSC
16074         test_241_bio 1000 $bsize &
16075         PID=$!
16076         test_241_dio 1000 $bsize
16077         wait $PID
16078 }
16079 run_test 241a "bio vs dio"
16080
16081 test_241b() {
16082         local bsize=$PAGE_SIZE
16083
16084         (( bsize < 40960 )) && bsize=40960
16085         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16086         ls -la $DIR/$tfile
16087         test_241_dio 1000 $bsize &
16088         PID=$!
16089         test_241_dio 1000 $bsize
16090         wait $PID
16091 }
16092 run_test 241b "dio vs dio"
16093
16094 test_242() {
16095         remote_mds_nodsh && skip "remote MDS with nodsh"
16096
16097         mkdir -p $DIR/$tdir
16098         touch $DIR/$tdir/$tfile
16099
16100         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
16101         do_facet mds1 lctl set_param fail_loc=0x105
16102         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
16103
16104         do_facet mds1 lctl set_param fail_loc=0
16105         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
16106 }
16107 run_test 242 "mdt_readpage failure should not cause directory unreadable"
16108
16109 test_243()
16110 {
16111         test_mkdir $DIR/$tdir
16112         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
16113 }
16114 run_test 243 "various group lock tests"
16115
16116 test_244()
16117 {
16118         test_mkdir $DIR/$tdir
16119         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
16120         sendfile_grouplock $DIR/$tdir/$tfile || \
16121                 error "sendfile+grouplock failed"
16122         rm -rf $DIR/$tdir
16123 }
16124 run_test 244 "sendfile with group lock tests"
16125
16126 test_245() {
16127         local flagname="multi_mod_rpcs"
16128         local connect_data_name="max_mod_rpcs"
16129         local out
16130
16131         # check if multiple modify RPCs flag is set
16132         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
16133                 grep "connect_flags:")
16134         echo "$out"
16135
16136         echo "$out" | grep -qw $flagname
16137         if [ $? -ne 0 ]; then
16138                 echo "connect flag $flagname is not set"
16139                 return
16140         fi
16141
16142         # check if multiple modify RPCs data is set
16143         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
16144         echo "$out"
16145
16146         echo "$out" | grep -qw $connect_data_name ||
16147                 error "import should have connect data $connect_data_name"
16148 }
16149 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
16150
16151 test_246() { # LU-7371
16152         remote_ost_nodsh && skip "remote OST with nodsh"
16153         [ $OST1_VERSION -lt $(version_code 2.7.62) ] &&
16154                 skip "Need OST version >= 2.7.62"
16155
16156         do_facet ost1 $LCTL set_param fail_val=4095
16157 #define OBD_FAIL_OST_READ_SIZE          0x234
16158         do_facet ost1 $LCTL set_param fail_loc=0x234
16159         $LFS setstripe $DIR/$tfile -i 0 -c 1
16160         dd if=/dev/zero of=$DIR/$tfile bs=4095 count=1 > /dev/null 2>&1
16161         cancel_lru_locks $FSNAME-OST0000
16162         dd if=$DIR/$tfile of=/dev/null bs=1048576 || error "Read failed"
16163 }
16164 run_test 246 "Read file of size 4095 should return right length"
16165
16166 cleanup_247() {
16167         local submount=$1
16168
16169         trap 0
16170         umount_client $submount
16171         rmdir $submount
16172 }
16173
16174 test_247a() {
16175         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16176                 grep -q subtree ||
16177                 skip_env "Fileset feature is not supported"
16178
16179         local submount=${MOUNT}_$tdir
16180
16181         mkdir $MOUNT/$tdir
16182         mkdir -p $submount || error "mkdir $submount failed"
16183         FILESET="$FILESET/$tdir" mount_client $submount ||
16184                 error "mount $submount failed"
16185         trap "cleanup_247 $submount" EXIT
16186         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
16187         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
16188                 error "read $MOUNT/$tdir/$tfile failed"
16189         cleanup_247 $submount
16190 }
16191 run_test 247a "mount subdir as fileset"
16192
16193 test_247b() {
16194         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16195                 skip_env "Fileset feature is not supported"
16196
16197         local submount=${MOUNT}_$tdir
16198
16199         rm -rf $MOUNT/$tdir
16200         mkdir -p $submount || error "mkdir $submount failed"
16201         SKIP_FILESET=1
16202         FILESET="$FILESET/$tdir" mount_client $submount &&
16203                 error "mount $submount should fail"
16204         rmdir $submount
16205 }
16206 run_test 247b "mount subdir that dose not exist"
16207
16208 test_247c() {
16209         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16210                 skip_env "Fileset feature is not supported"
16211
16212         local submount=${MOUNT}_$tdir
16213
16214         mkdir -p $MOUNT/$tdir/dir1
16215         mkdir -p $submount || error "mkdir $submount failed"
16216         trap "cleanup_247 $submount" EXIT
16217         FILESET="$FILESET/$tdir" mount_client $submount ||
16218                 error "mount $submount failed"
16219         local fid=$($LFS path2fid $MOUNT/)
16220         $LFS fid2path $submount $fid && error "fid2path should fail"
16221         cleanup_247 $submount
16222 }
16223 run_test 247c "running fid2path outside root"
16224
16225 test_247d() {
16226         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16227                 skip "Fileset feature is not supported"
16228
16229         local submount=${MOUNT}_$tdir
16230
16231         mkdir -p $MOUNT/$tdir/dir1
16232         mkdir -p $submount || error "mkdir $submount failed"
16233         FILESET="$FILESET/$tdir" mount_client $submount ||
16234                 error "mount $submount failed"
16235         trap "cleanup_247 $submount" EXIT
16236         local fid=$($LFS path2fid $submount/dir1)
16237         $LFS fid2path $submount $fid || error "fid2path should succeed"
16238         cleanup_247 $submount
16239 }
16240 run_test 247d "running fid2path inside root"
16241
16242 # LU-8037
16243 test_247e() {
16244         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16245                 grep -q subtree ||
16246                 skip "Fileset feature is not supported"
16247
16248         local submount=${MOUNT}_$tdir
16249
16250         mkdir $MOUNT/$tdir
16251         mkdir -p $submount || error "mkdir $submount failed"
16252         FILESET="$FILESET/.." mount_client $submount &&
16253                 error "mount $submount should fail"
16254         rmdir $submount
16255 }
16256 run_test 247e "mount .. as fileset"
16257
16258 test_248() {
16259         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
16260         [ -z "$fast_read_sav" ] && skip "no fast read support"
16261
16262         # create a large file for fast read verification
16263         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
16264
16265         # make sure the file is created correctly
16266         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
16267                 { rm -f $DIR/$tfile; skip "file creation error"; }
16268
16269         echo "Test 1: verify that fast read is 4 times faster on cache read"
16270
16271         # small read with fast read enabled
16272         $LCTL set_param -n llite.*.fast_read=1
16273         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16274                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16275                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16276         # small read with fast read disabled
16277         $LCTL set_param -n llite.*.fast_read=0
16278         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16279                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16280                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16281
16282         # verify that fast read is 4 times faster for cache read
16283         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
16284                 error_not_in_vm "fast read was not 4 times faster: " \
16285                            "$t_fast vs $t_slow"
16286
16287         echo "Test 2: verify the performance between big and small read"
16288         $LCTL set_param -n llite.*.fast_read=1
16289
16290         # 1k non-cache read
16291         cancel_lru_locks osc
16292         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16293                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16294                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16295
16296         # 1M non-cache read
16297         cancel_lru_locks osc
16298         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16299                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16300                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16301
16302         # verify that big IO is not 4 times faster than small IO
16303         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
16304                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
16305
16306         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
16307         rm -f $DIR/$tfile
16308 }
16309 run_test 248 "fast read verification"
16310
16311 test_249() { # LU-7890
16312         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
16313                 skip "Need at least version 2.8.54"
16314
16315         rm -f $DIR/$tfile
16316         $LFS setstripe -c 1 $DIR/$tfile
16317         # Offset 2T == 4k * 512M
16318         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
16319                 error "dd to 2T offset failed"
16320 }
16321 run_test 249 "Write above 2T file size"
16322
16323 test_250() {
16324         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
16325          && skip "no 16TB file size limit on ZFS"
16326
16327         $LFS setstripe -c 1 $DIR/$tfile
16328         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
16329         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
16330         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
16331         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
16332                 conv=notrunc,fsync && error "append succeeded"
16333         return 0
16334 }
16335 run_test 250 "Write above 16T limit"
16336
16337 test_251() {
16338         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
16339
16340         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
16341         #Skip once - writing the first stripe will succeed
16342         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16343         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
16344                 error "short write happened"
16345
16346         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16347         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
16348                 error "short read happened"
16349
16350         rm -f $DIR/$tfile
16351 }
16352 run_test 251 "Handling short read and write correctly"
16353
16354 test_252() {
16355         remote_mds_nodsh && skip "remote MDS with nodsh"
16356         remote_ost_nodsh && skip "remote OST with nodsh"
16357         if [ "$ost1_FSTYPE" != "ldiskfs" -o "$mds1_FSTYPE" != "ldiskfs" ]; then
16358                 skip_env "ldiskfs only test"
16359         fi
16360
16361         local tgt
16362         local dev
16363         local out
16364         local uuid
16365         local num
16366         local gen
16367
16368         # check lr_reader on OST0000
16369         tgt=ost1
16370         dev=$(facet_device $tgt)
16371         out=$(do_facet $tgt $LR_READER $dev)
16372         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16373         echo "$out"
16374         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
16375         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
16376                 error "Invalid uuid returned by $LR_READER on target $tgt"
16377         echo -e "uuid returned by $LR_READER is '$uuid'\n"
16378
16379         # check lr_reader -c on MDT0000
16380         tgt=mds1
16381         dev=$(facet_device $tgt)
16382         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
16383                 skip "$LR_READER does not support additional options"
16384         fi
16385         out=$(do_facet $tgt $LR_READER -c $dev)
16386         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16387         echo "$out"
16388         num=$(echo "$out" | grep -c "mdtlov")
16389         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
16390                 error "Invalid number of mdtlov clients returned by $LR_READER"
16391         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
16392
16393         # check lr_reader -cr on MDT0000
16394         out=$(do_facet $tgt $LR_READER -cr $dev)
16395         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16396         echo "$out"
16397         echo "$out" | grep -q "^reply_data:$" ||
16398                 error "$LR_READER should have returned 'reply_data' section"
16399         num=$(echo "$out" | grep -c "client_generation")
16400         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
16401 }
16402 run_test 252 "check lr_reader tool"
16403
16404 test_253_fill_ost() {
16405         local size_mb #how many MB should we write to pass watermark
16406         local lwm=$3  #low watermark
16407         local free_10mb #10% of free space
16408
16409         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16410         size_mb=$((free_kb / 1024 - lwm))
16411         free_10mb=$((free_kb / 10240))
16412         #If 10% of free space cross low watermark use it
16413         if (( free_10mb > size_mb )); then
16414                 size_mb=$free_10mb
16415         else
16416                 #At least we need to store 1.1 of difference between
16417                 #free space and low watermark
16418                 size_mb=$((size_mb + size_mb / 10))
16419         fi
16420         if (( lwm <= $((free_kb / 1024)) )) || [ ! -f $DIR/$tdir/1 ]; then
16421                 dd if=/dev/zero of=$DIR/$tdir/1 bs=1M count=$size_mb \
16422                          oflag=append conv=notrunc
16423         fi
16424
16425         sleep_maxage
16426
16427         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16428         echo "OST still has $((free_kb / 1024)) mbytes free"
16429 }
16430
16431 test_253() {
16432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16433         remote_mds_nodsh && skip "remote MDS with nodsh"
16434         remote_mgs_nodsh && skip "remote MGS with nodsh"
16435
16436         local ostidx=0
16437         local rc=0
16438
16439         local ost_name=$($LFS osts |
16440                 sed -n 's/^'$ostidx': \(.*\)_UUID .*/\1/p')
16441         # on the mdt's osc
16442         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
16443         do_facet $SINGLEMDS $LCTL get_param -n \
16444                 osp.$mdtosc_proc1.reserved_mb_high ||
16445                 skip  "remote MDS does not support reserved_mb_high"
16446
16447         rm -rf $DIR/$tdir
16448         wait_mds_ost_sync
16449         wait_delete_completed
16450         mkdir $DIR/$tdir
16451
16452         local last_wm_h=$(do_facet $SINGLEMDS $LCTL get_param -n \
16453                         osp.$mdtosc_proc1.reserved_mb_high)
16454         local last_wm_l=$(do_facet $SINGLEMDS $LCTL get_param -n \
16455                         osp.$mdtosc_proc1.reserved_mb_low)
16456         echo "prev high watermark $last_wm_h, prev low watermark $last_wm_l"
16457
16458         if ! combined_mgs_mds ; then
16459                 mount_mgs_client
16460         fi
16461         create_pool $FSNAME.$TESTNAME || error "Pool creation failed"
16462         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $ost_name ||
16463                 error "Adding $ost_name to pool failed"
16464
16465         # Wait for client to see a OST at pool
16466         wait_update $HOSTNAME "$LCTL get_param -n
16467                 lov.$FSNAME-*.pools.$TESTNAME | sort -u |
16468                 grep $ost_name" "$ost_name""_UUID" $((TIMEOUT/2)) ||
16469                 error "Client can not see the pool"
16470         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
16471                 error "Setstripe failed"
16472
16473         dd if=/dev/zero of=$DIR/$tdir/0 bs=1M count=10
16474         local blocks=$($LFS df $MOUNT | grep $ost_name | awk '{ print $4 }')
16475         echo "OST still has $((blocks/1024)) mbytes free"
16476
16477         local new_lwm=$((blocks/1024-10))
16478         do_facet $SINGLEMDS $LCTL set_param \
16479                         osp.$mdtosc_proc1.reserved_mb_high=$((new_lwm+5))
16480         do_facet $SINGLEMDS $LCTL set_param \
16481                         osp.$mdtosc_proc1.reserved_mb_low=$new_lwm
16482
16483         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16484
16485         #First enospc could execute orphan deletion so repeat.
16486         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16487
16488         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16489                         osp.$mdtosc_proc1.prealloc_status)
16490         echo "prealloc_status $oa_status"
16491
16492         dd if=/dev/zero of=$DIR/$tdir/2 bs=1M count=1 &&
16493                 error "File creation should fail"
16494         #object allocation was stopped, but we still able to append files
16495         dd if=/dev/zero of=$DIR/$tdir/1 bs=1M seek=6 count=5 oflag=append ||
16496                 error "Append failed"
16497         rm -f $DIR/$tdir/1 $DIR/$tdir/0 $DIR/$tdir/r*
16498
16499         wait_delete_completed
16500
16501         sleep_maxage
16502
16503         for i in $(seq 10 12); do
16504                 dd if=/dev/zero of=$DIR/$tdir/$i bs=1M count=1 2>/dev/null ||
16505                         error "File creation failed after rm";
16506         done
16507
16508         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16509                         osp.$mdtosc_proc1.prealloc_status)
16510         echo "prealloc_status $oa_status"
16511
16512         if (( oa_status != 0 )); then
16513                 error "Object allocation still disable after rm"
16514         fi
16515         do_facet $SINGLEMDS $LCTL set_param \
16516                         osp.$mdtosc_proc1.reserved_mb_high=$last_wm_h
16517         do_facet $SINGLEMDS $LCTL set_param \
16518                         osp.$mdtosc_proc1.reserved_mb_low=$last_wm_l
16519
16520
16521         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $ost_name ||
16522                 error "Remove $ost_name from pool failed"
16523         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
16524                 error "Pool destroy fialed"
16525
16526         if ! combined_mgs_mds ; then
16527                 umount_mgs_client
16528         fi
16529 }
16530 run_test 253 "Check object allocation limit"
16531
16532 test_254() {
16533         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16534         remote_mds_nodsh && skip "remote MDS with nodsh"
16535         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
16536                 skip "MDS does not support changelog_size"
16537
16538         local cl_user
16539         local MDT0=$(facet_svc $SINGLEMDS)
16540
16541         changelog_register || error "changelog_register failed"
16542
16543         changelog_clear 0 || error "changelog_clear failed"
16544
16545         local size1=$(do_facet $SINGLEMDS \
16546                       $LCTL get_param -n mdd.$MDT0.changelog_size)
16547         echo "Changelog size $size1"
16548
16549         rm -rf $DIR/$tdir
16550         $LFS mkdir -i 0 $DIR/$tdir
16551         # change something
16552         mkdir -p $DIR/$tdir/pics/2008/zachy
16553         touch $DIR/$tdir/pics/2008/zachy/timestamp
16554         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
16555         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16556         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16557         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16558         rm $DIR/$tdir/pics/desktop.jpg
16559
16560         local size2=$(do_facet $SINGLEMDS \
16561                       $LCTL get_param -n mdd.$MDT0.changelog_size)
16562         echo "Changelog size after work $size2"
16563
16564         (( $size2 > $size1 )) ||
16565                 error "new Changelog size=$size2 less than old size=$size1"
16566 }
16567 run_test 254 "Check changelog size"
16568
16569 ladvise_no_type()
16570 {
16571         local type=$1
16572         local file=$2
16573
16574         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
16575                 awk -F: '{print $2}' | grep $type > /dev/null
16576         if [ $? -ne 0 ]; then
16577                 return 0
16578         fi
16579         return 1
16580 }
16581
16582 ladvise_no_ioctl()
16583 {
16584         local file=$1
16585
16586         lfs ladvise -a willread $file > /dev/null 2>&1
16587         if [ $? -eq 0 ]; then
16588                 return 1
16589         fi
16590
16591         lfs ladvise -a willread $file 2>&1 |
16592                 grep "Inappropriate ioctl for device" > /dev/null
16593         if [ $? -eq 0 ]; then
16594                 return 0
16595         fi
16596         return 1
16597 }
16598
16599 percent() {
16600         bc <<<"scale=2; ($1 - $2) * 100 / $2"
16601 }
16602
16603 # run a random read IO workload
16604 # usage: random_read_iops <filename> <filesize> <iosize>
16605 random_read_iops() {
16606         local file=$1
16607         local fsize=$2
16608         local iosize=${3:-4096}
16609
16610         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
16611                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
16612 }
16613
16614 drop_file_oss_cache() {
16615         local file="$1"
16616         local nodes="$2"
16617
16618         $LFS ladvise -a dontneed $file 2>/dev/null ||
16619                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
16620 }
16621
16622 ladvise_willread_performance()
16623 {
16624         local repeat=10
16625         local average_origin=0
16626         local average_cache=0
16627         local average_ladvise=0
16628
16629         for ((i = 1; i <= $repeat; i++)); do
16630                 echo "Iter $i/$repeat: reading without willread hint"
16631                 cancel_lru_locks osc
16632                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
16633                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
16634                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
16635                 average_origin=$(bc <<<"$average_origin + $speed_origin")
16636
16637                 cancel_lru_locks osc
16638                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
16639                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
16640                 average_cache=$(bc <<<"$average_cache + $speed_cache")
16641
16642                 cancel_lru_locks osc
16643                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
16644                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
16645                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
16646                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
16647                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
16648         done
16649         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
16650         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
16651         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
16652
16653         speedup_cache=$(percent $average_cache $average_origin)
16654         speedup_ladvise=$(percent $average_ladvise $average_origin)
16655
16656         echo "Average uncached read: $average_origin"
16657         echo "Average speedup with OSS cached read: " \
16658                 "$average_cache = +$speedup_cache%"
16659         echo "Average speedup with ladvise willread: " \
16660                 "$average_ladvise = +$speedup_ladvise%"
16661
16662         local lowest_speedup=20
16663         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
16664                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
16665                         "got $average_cache%. Skipping ladvise willread check."
16666                 return 0
16667         fi
16668
16669         # the test won't work on ZFS until it supports 'ladvise dontneed', but
16670         # it is still good to run until then to exercise 'ladvise willread'
16671         ! $LFS ladvise -a dontneed $DIR/$tfile &&
16672                 [ "$ost1_FSTYPE" = "zfs" ] &&
16673                 echo "osd-zfs does not support dontneed or drop_caches" &&
16674                 return 0
16675
16676         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
16677         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
16678                 error_not_in_vm "Speedup with willread is less than " \
16679                         "$lowest_speedup%, got $average_ladvise%"
16680 }
16681
16682 test_255a() {
16683         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
16684                 skip "lustre < 2.8.54 does not support ladvise "
16685         remote_ost_nodsh && skip "remote OST with nodsh"
16686
16687         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
16688
16689         ladvise_no_type willread $DIR/$tfile &&
16690                 skip "willread ladvise is not supported"
16691
16692         ladvise_no_ioctl $DIR/$tfile &&
16693                 skip "ladvise ioctl is not supported"
16694
16695         local size_mb=100
16696         local size=$((size_mb * 1048576))
16697         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
16698                 error "dd to $DIR/$tfile failed"
16699
16700         lfs ladvise -a willread $DIR/$tfile ||
16701                 error "Ladvise failed with no range argument"
16702
16703         lfs ladvise -a willread -s 0 $DIR/$tfile ||
16704                 error "Ladvise failed with no -l or -e argument"
16705
16706         lfs ladvise -a willread -e 1 $DIR/$tfile ||
16707                 error "Ladvise failed with only -e argument"
16708
16709         lfs ladvise -a willread -l 1 $DIR/$tfile ||
16710                 error "Ladvise failed with only -l argument"
16711
16712         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
16713                 error "End offset should not be smaller than start offset"
16714
16715         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
16716                 error "End offset should not be equal to start offset"
16717
16718         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
16719                 error "Ladvise failed with overflowing -s argument"
16720
16721         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
16722                 error "Ladvise failed with overflowing -e argument"
16723
16724         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
16725                 error "Ladvise failed with overflowing -l argument"
16726
16727         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
16728                 error "Ladvise succeeded with conflicting -l and -e arguments"
16729
16730         echo "Synchronous ladvise should wait"
16731         local delay=4
16732 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
16733         do_nodes $(comma_list $(osts_nodes)) \
16734                 $LCTL set_param fail_val=$delay fail_loc=0x237
16735
16736         local start_ts=$SECONDS
16737         lfs ladvise -a willread $DIR/$tfile ||
16738                 error "Ladvise failed with no range argument"
16739         local end_ts=$SECONDS
16740         local inteval_ts=$((end_ts - start_ts))
16741
16742         if [ $inteval_ts -lt $(($delay - 1)) ]; then
16743                 error "Synchronous advice didn't wait reply"
16744         fi
16745
16746         echo "Asynchronous ladvise shouldn't wait"
16747         local start_ts=$SECONDS
16748         lfs ladvise -a willread -b $DIR/$tfile ||
16749                 error "Ladvise failed with no range argument"
16750         local end_ts=$SECONDS
16751         local inteval_ts=$((end_ts - start_ts))
16752
16753         if [ $inteval_ts -gt $(($delay / 2)) ]; then
16754                 error "Asynchronous advice blocked"
16755         fi
16756
16757         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
16758         ladvise_willread_performance
16759 }
16760 run_test 255a "check 'lfs ladvise -a willread'"
16761
16762 facet_meminfo() {
16763         local facet=$1
16764         local info=$2
16765
16766         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
16767 }
16768
16769 test_255b() {
16770         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
16771                 skip "lustre < 2.8.54 does not support ladvise "
16772         remote_ost_nodsh && skip "remote OST with nodsh"
16773
16774         lfs setstripe -c 1 -i 0 $DIR/$tfile
16775
16776         ladvise_no_type dontneed $DIR/$tfile &&
16777                 skip "dontneed ladvise is not supported"
16778
16779         ladvise_no_ioctl $DIR/$tfile &&
16780                 skip "ladvise ioctl is not supported"
16781
16782         ! $LFS ladvise -a dontneed $DIR/$tfile &&
16783                 [ "$ost1_FSTYPE" = "zfs" ] &&
16784                 skip "zfs-osd does not support 'ladvise dontneed'"
16785
16786         local size_mb=100
16787         local size=$((size_mb * 1048576))
16788         # In order to prevent disturbance of other processes, only check 3/4
16789         # of the memory usage
16790         local kibibytes=$((size_mb * 1024 * 3 / 4))
16791
16792         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
16793                 error "dd to $DIR/$tfile failed"
16794
16795         #force write to complete before dropping OST cache & checking memory
16796         sync
16797
16798         local total=$(facet_meminfo ost1 MemTotal)
16799         echo "Total memory: $total KiB"
16800
16801         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
16802         local before_read=$(facet_meminfo ost1 Cached)
16803         echo "Cache used before read: $before_read KiB"
16804
16805         lfs ladvise -a willread $DIR/$tfile ||
16806                 error "Ladvise willread failed"
16807         local after_read=$(facet_meminfo ost1 Cached)
16808         echo "Cache used after read: $after_read KiB"
16809
16810         lfs ladvise -a dontneed $DIR/$tfile ||
16811                 error "Ladvise dontneed again failed"
16812         local no_read=$(facet_meminfo ost1 Cached)
16813         echo "Cache used after dontneed ladvise: $no_read KiB"
16814
16815         if [ $total -lt $((before_read + kibibytes)) ]; then
16816                 echo "Memory is too small, abort checking"
16817                 return 0
16818         fi
16819
16820         if [ $((before_read + kibibytes)) -gt $after_read ]; then
16821                 error "Ladvise willread should use more memory" \
16822                         "than $kibibytes KiB"
16823         fi
16824
16825         if [ $((no_read + kibibytes)) -gt $after_read ]; then
16826                 error "Ladvise dontneed should release more memory" \
16827                         "than $kibibytes KiB"
16828         fi
16829 }
16830 run_test 255b "check 'lfs ladvise -a dontneed'"
16831
16832 test_255c() {
16833         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
16834                 skip "lustre < 2.10.53 does not support lockahead"
16835
16836         local count
16837         local new_count
16838         local difference
16839         local i
16840         local rc
16841
16842         test_mkdir -p $DIR/$tdir
16843         $LFS setstripe -i 0 $DIR/$tdir
16844
16845         #test 10 returns only success/failure
16846         i=10
16847         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16848         rc=$?
16849         if [ $rc -eq 255 ]; then
16850                 error "Ladvise test${i} failed, ${rc}"
16851         fi
16852
16853         #test 11 counts lock enqueue requests, all others count new locks
16854         i=11
16855         count=$(do_facet ost1 \
16856                 $LCTL get_param -n ost.OSS.ost.stats)
16857         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
16858
16859         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16860         rc=$?
16861         if [ $rc -eq 255 ]; then
16862                 error "Ladvise test${i} failed, ${rc}"
16863         fi
16864
16865         new_count=$(do_facet ost1 \
16866                 $LCTL get_param -n ost.OSS.ost.stats)
16867         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
16868                    awk '{ print $2 }')
16869
16870         difference="$((new_count - count))"
16871         if [ $difference -ne $rc ]; then
16872                 error "Ladvise test${i}, bad enqueue count, returned " \
16873                       "${rc}, actual ${difference}"
16874         fi
16875
16876         for i in $(seq 12 21); do
16877                 # If we do not do this, we run the risk of having too many
16878                 # locks and starting lock cancellation while we are checking
16879                 # lock counts.
16880                 cancel_lru_locks osc
16881
16882                 count=$($LCTL get_param -n \
16883                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
16884
16885                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
16886                 rc=$?
16887                 if [ $rc -eq 255 ]; then
16888                         error "Ladvise test ${i} failed, ${rc}"
16889                 fi
16890
16891                 new_count=$($LCTL get_param -n \
16892                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
16893                 difference="$((new_count - count))"
16894
16895                 # Test 15 output is divided by 100 to map down to valid return
16896                 if [ $i -eq 15 ]; then
16897                         rc="$((rc * 100))"
16898                 fi
16899
16900                 if [ $difference -ne $rc ]; then
16901                         error "Ladvise test ${i}, bad lock count, returned " \
16902                               "${rc}, actual ${difference}"
16903                 fi
16904         done
16905
16906         #test 22 returns only success/failure
16907         i=22
16908         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16909         rc=$?
16910         if [ $rc -eq 255 ]; then
16911                 error "Ladvise test${i} failed, ${rc}"
16912         fi
16913 }
16914 run_test 255c "suite of ladvise lockahead tests"
16915
16916 test_256() {
16917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16918         remote_mds_nodsh && skip "remote MDS with nodsh"
16919         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
16920         changelog_users $SINGLEMDS | grep "^cl" &&
16921                 skip "active changelog user"
16922
16923         local cl_user
16924         local cat_sl
16925         local mdt_dev
16926
16927         mdt_dev=$(mdsdevname 1)
16928         echo $mdt_dev
16929
16930         changelog_register || error "changelog_register failed"
16931
16932         rm -rf $DIR/$tdir
16933         mkdir -p $DIR/$tdir
16934
16935         changelog_clear 0 || error "changelog_clear failed"
16936
16937         # change something
16938         touch $DIR/$tdir/{1..10}
16939
16940         # stop the MDT
16941         stop $SINGLEMDS || error "Fail to stop MDT"
16942
16943         # remount the MDT
16944
16945         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
16946
16947         #after mount new plainllog is used
16948         touch $DIR/$tdir/{11..19}
16949         local tmpfile=$(mktemp -u $tfile.XXXXXX)
16950         cat_sl=$(do_facet $SINGLEMDS "sync; \
16951                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
16952                  llog_reader $tmpfile | grep -c type=1064553b")
16953         do_facet $SINGLEMDS llog_reader $tmpfile
16954
16955         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
16956
16957         changelog_clear 0 || error "changelog_clear failed"
16958
16959         cat_sl=$(do_facet $SINGLEMDS "sync; \
16960                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
16961                  llog_reader $tmpfile | grep -c type=1064553b; rm -f $tmpfile")
16962
16963         if (( cat_sl == 2 )); then
16964                 error "Empty plain llog was not deleted from changelog catalog"
16965         elif (( cat_sl != 1 )); then
16966                 error "Active plain llog shouldn't be deleted from catalog"
16967         fi
16968 }
16969 run_test 256 "Check llog delete for empty and not full state"
16970
16971 test_257() {
16972         remote_mds_nodsh && skip "remote MDS with nodsh"
16973         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
16974                 skip "Need MDS version at least 2.8.55"
16975
16976         test_mkdir $DIR/$tdir
16977
16978         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
16979                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
16980         stat $DIR/$tdir
16981
16982 #define OBD_FAIL_MDS_XATTR_REP                  0x161
16983         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
16984         local facet=mds$((mdtidx + 1))
16985         set_nodes_failloc $(facet_active_host $facet) 0x80000161
16986         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
16987
16988         stop $facet || error "stop MDS failed"
16989         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
16990                 error "start MDS fail"
16991         wait_recovery_complete $facet
16992 }
16993 run_test 257 "xattr locks are not lost"
16994
16995 # Verify we take the i_mutex when security requires it
16996 test_258a() {
16997 #define OBD_FAIL_IMUTEX_SEC 0x141c
16998         $LCTL set_param fail_loc=0x141c
16999         touch $DIR/$tfile
17000         chmod u+s $DIR/$tfile
17001         chmod a+rwx $DIR/$tfile
17002         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17003         RC=$?
17004         if [ $RC -ne 0 ]; then
17005                 error "error, failed to take i_mutex, rc=$?"
17006         fi
17007         rm -f $DIR/$tfile
17008 }
17009 run_test 258a
17010
17011 # Verify we do NOT take the i_mutex in the normal case
17012 test_258b() {
17013 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
17014         $LCTL set_param fail_loc=0x141d
17015         touch $DIR/$tfile
17016         chmod a+rwx $DIR
17017         chmod a+rw $DIR/$tfile
17018         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17019         RC=$?
17020         if [ $RC -ne 0 ]; then
17021                 error "error, took i_mutex unnecessarily, rc=$?"
17022         fi
17023         rm -f $DIR/$tfile
17024
17025 }
17026 run_test 258b "verify i_mutex security behavior"
17027
17028 test_259() {
17029         local file=$DIR/$tfile
17030         local before
17031         local after
17032
17033         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17034
17035         stack_trap "rm -f $file" EXIT
17036
17037         wait_delete_completed
17038         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17039         echo "before: $before"
17040
17041         $LFS setstripe -i 0 -c 1 $file
17042         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
17043         sync_all_data
17044         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17045         echo "after write: $after"
17046
17047 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
17048         do_facet ost1 $LCTL set_param fail_loc=0x2301
17049         $TRUNCATE $file 0
17050         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17051         echo "after truncate: $after"
17052
17053         stop ost1
17054         do_facet ost1 $LCTL set_param fail_loc=0
17055         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17056         sleep 2
17057         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17058         echo "after restart: $after"
17059         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
17060                 error "missing truncate?"
17061
17062         return 0
17063 }
17064 run_test 259 "crash at delayed truncate"
17065
17066 test_260() {
17067 #define OBD_FAIL_MDC_CLOSE               0x806
17068         $LCTL set_param fail_loc=0x80000806
17069         touch $DIR/$tfile
17070
17071 }
17072 run_test 260 "Check mdc_close fail"
17073
17074 ### Data-on-MDT sanity tests ###
17075 test_270a() {
17076         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17077                 skip "Need MDS version at least 2.10.55 for DoM"
17078
17079         # create DoM file
17080         local dom=$DIR/$tdir/dom_file
17081         local tmp=$DIR/$tdir/tmp_file
17082
17083         mkdir -p $DIR/$tdir
17084
17085         # basic checks for DoM component creation
17086         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
17087                 error "Can set MDT layout to non-first entry"
17088
17089         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
17090                 error "Can define multiple entries as MDT layout"
17091
17092         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
17093
17094         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
17095         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
17096         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
17097
17098         local mdtidx=$($LFS getstripe -m $dom)
17099         local mdtname=MDT$(printf %04x $mdtidx)
17100         local facet=mds$((mdtidx + 1))
17101         local space_check=1
17102
17103         # Skip free space checks with ZFS
17104         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
17105
17106         # write
17107         sync
17108         local size_tmp=$((65536 * 3))
17109         local mdtfree1=$(do_facet $facet \
17110                          lctl get_param -n osd*.*$mdtname.kbytesfree)
17111
17112         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17113         # check also direct IO along write
17114         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
17115         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17116         sync
17117         cmp $tmp $dom || error "file data is different"
17118         [ $(stat -c%s $dom) == $size_tmp ] ||
17119                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17120         if [ $space_check == 1 ]; then
17121                 local mdtfree2=$(do_facet $facet \
17122                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
17123
17124                 # increase in usage from by $size_tmp
17125                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17126                         error "MDT free space wrong after write: " \
17127                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17128         fi
17129
17130         # truncate
17131         local size_dom=10000
17132
17133         $TRUNCATE $dom $size_dom
17134         [ $(stat -c%s $dom) == $size_dom ] ||
17135                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
17136         if [ $space_check == 1 ]; then
17137                 mdtfree1=$(do_facet $facet \
17138                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17139                 # decrease in usage from $size_tmp to new $size_dom
17140                 [ $(($mdtfree1 - $mdtfree2)) -ge \
17141                   $(((size_tmp - size_dom) / 1024)) ] ||
17142                         error "MDT free space is wrong after truncate: " \
17143                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
17144         fi
17145
17146         # append
17147         cat $tmp >> $dom
17148         sync
17149         size_dom=$((size_dom + size_tmp))
17150         [ $(stat -c%s $dom) == $size_dom ] ||
17151                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
17152         if [ $space_check == 1 ]; then
17153                 mdtfree2=$(do_facet $facet \
17154                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17155                 # increase in usage by $size_tmp from previous
17156                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17157                         error "MDT free space is wrong after append: " \
17158                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17159         fi
17160
17161         # delete
17162         rm $dom
17163         if [ $space_check == 1 ]; then
17164                 mdtfree1=$(do_facet $facet \
17165                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17166                 # decrease in usage by $size_dom from previous
17167                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
17168                         error "MDT free space is wrong after removal: " \
17169                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
17170         fi
17171
17172         # combined striping
17173         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
17174                 error "Can't create DoM + OST striping"
17175
17176         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
17177         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17178         # check also direct IO along write
17179         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17180         sync
17181         cmp $tmp $dom || error "file data is different"
17182         [ $(stat -c%s $dom) == $size_tmp ] ||
17183                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17184         rm $dom $tmp
17185
17186         return 0
17187 }
17188 run_test 270a "DoM: basic functionality tests"
17189
17190 test_270b() {
17191         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17192                 skip "Need MDS version at least 2.10.55"
17193
17194         local dom=$DIR/$tdir/dom_file
17195         local max_size=1048576
17196
17197         mkdir -p $DIR/$tdir
17198         $LFS setstripe -E $max_size -L mdt $dom
17199
17200         # truncate over the limit
17201         $TRUNCATE $dom $(($max_size + 1)) &&
17202                 error "successful truncate over the maximum size"
17203         # write over the limit
17204         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
17205                 error "successful write over the maximum size"
17206         # append over the limit
17207         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
17208         echo "12345" >> $dom && error "successful append over the maximum size"
17209         rm $dom
17210
17211         return 0
17212 }
17213 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
17214
17215 test_270c() {
17216         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17217                 skip "Need MDS version at least 2.10.55"
17218
17219         mkdir -p $DIR/$tdir
17220         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17221
17222         # check files inherit DoM EA
17223         touch $DIR/$tdir/first
17224         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
17225                 error "bad pattern"
17226         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
17227                 error "bad stripe count"
17228         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
17229                 error "bad stripe size"
17230
17231         # check directory inherits DoM EA and uses it as default
17232         mkdir $DIR/$tdir/subdir
17233         touch $DIR/$tdir/subdir/second
17234         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
17235                 error "bad pattern in sub-directory"
17236         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
17237                 error "bad stripe count in sub-directory"
17238         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
17239                 error "bad stripe size in sub-directory"
17240         return 0
17241 }
17242 run_test 270c "DoM: DoM EA inheritance tests"
17243
17244 test_270d() {
17245         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17246                 skip "Need MDS version at least 2.10.55"
17247
17248         mkdir -p $DIR/$tdir
17249         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17250
17251         # inherit default DoM striping
17252         mkdir $DIR/$tdir/subdir
17253         touch $DIR/$tdir/subdir/f1
17254
17255         # change default directory striping
17256         $LFS setstripe -c 1 $DIR/$tdir/subdir
17257         touch $DIR/$tdir/subdir/f2
17258         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
17259                 error "wrong default striping in file 2"
17260         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
17261                 error "bad pattern in file 2"
17262         return 0
17263 }
17264 run_test 270d "DoM: change striping from DoM to RAID0"
17265
17266 test_270e() {
17267         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17268                 skip "Need MDS version at least 2.10.55"
17269
17270         mkdir -p $DIR/$tdir/dom
17271         mkdir -p $DIR/$tdir/norm
17272         DOMFILES=20
17273         NORMFILES=10
17274         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
17275         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
17276
17277         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
17278         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
17279
17280         # find DoM files by layout
17281         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
17282         [ $NUM -eq  $DOMFILES ] ||
17283                 error "lfs find -L: found $NUM, expected $DOMFILES"
17284         echo "Test 1: lfs find 20 DOM files by layout: OK"
17285
17286         # there should be 1 dir with default DOM striping
17287         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
17288         [ $NUM -eq  1 ] ||
17289                 error "lfs find -L: found $NUM, expected 1 dir"
17290         echo "Test 2: lfs find 1 DOM dir by layout: OK"
17291
17292         # find DoM files by stripe size
17293         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
17294         [ $NUM -eq  $DOMFILES ] ||
17295                 error "lfs find -S: found $NUM, expected $DOMFILES"
17296         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
17297
17298         # find files by stripe offset except DoM files
17299         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
17300         [ $NUM -eq  $NORMFILES ] ||
17301                 error "lfs find -i: found $NUM, expected $NORMFILES"
17302         echo "Test 5: lfs find no DOM files by stripe index: OK"
17303         return 0
17304 }
17305 run_test 270e "DoM: lfs find with DoM files test"
17306
17307 test_270f() {
17308         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17309                 skip "Need MDS version at least 2.10.55"
17310
17311         local mdtname=${FSNAME}-MDT0000-mdtlov
17312         local dom=$DIR/$tdir/dom_file
17313         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
17314                                                 lod.$mdtname.dom_stripesize)
17315         local dom_limit=131072
17316
17317         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
17318         local dom_current=$(do_facet mds1 $LCTL get_param -n \
17319                                                 lod.$mdtname.dom_stripesize)
17320         [ ${dom_limit} -eq ${dom_current} ] ||
17321                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
17322
17323         $LFS mkdir -i 0 -c 1 $DIR/$tdir
17324         $LFS setstripe -d $DIR/$tdir
17325         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
17326                 error "Can't set directory default striping"
17327
17328         # exceed maximum stripe size
17329         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17330                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
17331         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
17332                 error "Able to create DoM component size more than LOD limit"
17333
17334         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
17335         dom_current=$(do_facet mds1 $LCTL get_param -n \
17336                                                 lod.$mdtname.dom_stripesize)
17337         [ 0 -eq ${dom_current} ] ||
17338                 error "Can't set zero DoM stripe limit"
17339         rm $dom
17340
17341         # attempt to create DoM file on server with disabled DoM should
17342         # remove DoM entry from layout and be succeed
17343         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
17344                 error "Can't create DoM file (DoM is disabled)"
17345         [ $($LFS getstripe -L $dom) == "mdt" ] &&
17346                 error "File has DoM component while DoM is disabled"
17347         rm $dom
17348
17349         # attempt to create DoM file with only DoM stripe should return error
17350         $LFS setstripe -E $dom_limit -L mdt $dom &&
17351                 error "Able to create DoM-only file while DoM is disabled"
17352
17353         # too low values to be aligned with smallest stripe size 64K
17354         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
17355         dom_current=$(do_facet mds1 $LCTL get_param -n \
17356                                                 lod.$mdtname.dom_stripesize)
17357         [ 30000 -eq ${dom_current} ] &&
17358                 error "Can set too small DoM stripe limit"
17359
17360         # 64K is a minimal stripe size in Lustre, expect limit of that size
17361         [ 65536 -eq ${dom_current} ] ||
17362                 error "Limit is not set to 64K but ${dom_current}"
17363
17364         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
17365         dom_current=$(do_facet mds1 $LCTL get_param -n \
17366                                                 lod.$mdtname.dom_stripesize)
17367         echo $dom_current
17368         [ 2147483648 -eq ${dom_current} ] &&
17369                 error "Can set too large DoM stripe limit"
17370
17371         do_facet mds1 $LCTL set_param -n \
17372                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
17373         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17374                 error "Can't create DoM component size after limit change"
17375         do_facet mds1 $LCTL set_param -n \
17376                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
17377         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
17378                 error "Can't create DoM file after limit decrease"
17379         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
17380                 error "Can create big DoM component after limit decrease"
17381         touch ${dom}_def ||
17382                 error "Can't create file with old default layout"
17383
17384         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
17385         return 0
17386 }
17387 run_test 270f "DoM: maximum DoM stripe size checks"
17388
17389 test_271a() {
17390         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17391                 skip "Need MDS version at least 2.10.55"
17392
17393         local dom=$DIR/$tdir/dom
17394
17395         mkdir -p $DIR/$tdir
17396
17397         $LFS setstripe -E 1024K -L mdt $dom
17398
17399         lctl set_param -n mdc.*.stats=clear
17400         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17401         cat $dom > /dev/null
17402         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
17403         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
17404         ls $dom
17405         rm -f $dom
17406 }
17407 run_test 271a "DoM: data is cached for read after write"
17408
17409 test_271b() {
17410         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17411                 skip "Need MDS version at least 2.10.55"
17412
17413         local dom=$DIR/$tdir/dom
17414
17415         mkdir -p $DIR/$tdir
17416
17417         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17418
17419         lctl set_param -n mdc.*.stats=clear
17420         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17421         cancel_lru_locks mdc
17422         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
17423         # second stat to check size is cached on client
17424         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
17425         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17426         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
17427         rm -f $dom
17428 }
17429 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
17430
17431 test_271ba() {
17432         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17433                 skip "Need MDS version at least 2.10.55"
17434
17435         local dom=$DIR/$tdir/dom
17436
17437         mkdir -p $DIR/$tdir
17438
17439         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17440
17441         lctl set_param -n mdc.*.stats=clear
17442         lctl set_param -n osc.*.stats=clear
17443         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
17444         cancel_lru_locks mdc
17445         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17446         # second stat to check size is cached on client
17447         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17448         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17449         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
17450         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
17451         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
17452         rm -f $dom
17453 }
17454 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
17455
17456
17457 get_mdc_stats() {
17458         local mdtidx=$1
17459         local param=$2
17460         local mdt=MDT$(printf %04x $mdtidx)
17461
17462         if [ -z $param ]; then
17463                 lctl get_param -n mdc.*$mdt*.stats
17464         else
17465                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
17466         fi
17467 }
17468
17469 test_271c() {
17470         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17471                 skip "Need MDS version at least 2.10.55"
17472
17473         local dom=$DIR/$tdir/dom
17474
17475         mkdir -p $DIR/$tdir
17476
17477         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17478
17479         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17480         local facet=mds$((mdtidx + 1))
17481
17482         cancel_lru_locks mdc
17483         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
17484         createmany -o $dom 1000
17485         lctl set_param -n mdc.*.stats=clear
17486         smalliomany -w $dom 1000 200
17487         get_mdc_stats $mdtidx
17488         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17489         # Each file has 1 open, 1 IO enqueues, total 2000
17490         # but now we have also +1 getxattr for security.capability, total 3000
17491         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
17492         unlinkmany $dom 1000
17493
17494         cancel_lru_locks mdc
17495         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
17496         createmany -o $dom 1000
17497         lctl set_param -n mdc.*.stats=clear
17498         smalliomany -w $dom 1000 200
17499         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17500         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
17501         # for OPEN and IO lock.
17502         [ $((enq - enq_2)) -ge 1000 ] ||
17503                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
17504         unlinkmany $dom 1000
17505         return 0
17506 }
17507 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
17508
17509 cleanup_271def_tests() {
17510         trap 0
17511         rm -f $1
17512 }
17513
17514 test_271d() {
17515         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17516                 skip "Need MDS version at least 2.10.57"
17517
17518         local dom=$DIR/$tdir/dom
17519         local tmp=$TMP/$tfile
17520         trap "cleanup_271def_tests $tmp" EXIT
17521
17522         mkdir -p $DIR/$tdir
17523
17524         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17525
17526         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17527
17528         cancel_lru_locks mdc
17529         dd if=/dev/urandom of=$tmp bs=1000 count=1
17530         dd if=$tmp of=$dom bs=1000 count=1
17531         cancel_lru_locks mdc
17532
17533         cat /etc/hosts >> $tmp
17534         lctl set_param -n mdc.*.stats=clear
17535
17536         # append data to the same file it should update local page
17537         echo "Append to the same page"
17538         cat /etc/hosts >> $dom
17539         local num=$(get_mdc_stats $mdtidx ost_read)
17540         local ra=$(get_mdc_stats $mdtidx req_active)
17541         local rw=$(get_mdc_stats $mdtidx req_waittime)
17542
17543         [ -z $num ] || error "$num READ RPC occured"
17544         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17545         echo "... DONE"
17546
17547         # compare content
17548         cmp $tmp $dom || error "file miscompare"
17549
17550         cancel_lru_locks mdc
17551         lctl set_param -n mdc.*.stats=clear
17552
17553         echo "Open and read file"
17554         cat $dom > /dev/null
17555         local num=$(get_mdc_stats $mdtidx ost_read)
17556         local ra=$(get_mdc_stats $mdtidx req_active)
17557         local rw=$(get_mdc_stats $mdtidx req_waittime)
17558
17559         [ -z $num ] || error "$num READ RPC occured"
17560         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17561         echo "... DONE"
17562
17563         # compare content
17564         cmp $tmp $dom || error "file miscompare"
17565
17566         return 0
17567 }
17568 run_test 271d "DoM: read on open (1K file in reply buffer)"
17569
17570 test_271f() {
17571         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17572                 skip "Need MDS version at least 2.10.57"
17573
17574         local dom=$DIR/$tdir/dom
17575         local tmp=$TMP/$tfile
17576         trap "cleanup_271def_tests $tmp" EXIT
17577
17578         mkdir -p $DIR/$tdir
17579
17580         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17581
17582         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17583
17584         cancel_lru_locks mdc
17585         dd if=/dev/urandom of=$tmp bs=200000 count=1
17586         dd if=$tmp of=$dom bs=200000 count=1
17587         cancel_lru_locks mdc
17588         cat /etc/hosts >> $tmp
17589         lctl set_param -n mdc.*.stats=clear
17590
17591         echo "Append to the same page"
17592         cat /etc/hosts >> $dom
17593         local num=$(get_mdc_stats $mdtidx ost_read)
17594         local ra=$(get_mdc_stats $mdtidx req_active)
17595         local rw=$(get_mdc_stats $mdtidx req_waittime)
17596
17597         [ -z $num ] || error "$num READ RPC occured"
17598         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17599         echo "... DONE"
17600
17601         # compare content
17602         cmp $tmp $dom || error "file miscompare"
17603
17604         cancel_lru_locks mdc
17605         lctl set_param -n mdc.*.stats=clear
17606
17607         echo "Open and read file"
17608         cat $dom > /dev/null
17609         local num=$(get_mdc_stats $mdtidx ost_read)
17610         local ra=$(get_mdc_stats $mdtidx req_active)
17611         local rw=$(get_mdc_stats $mdtidx req_waittime)
17612
17613         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
17614         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17615         echo "... DONE"
17616
17617         # compare content
17618         cmp $tmp $dom || error "file miscompare"
17619
17620         return 0
17621 }
17622 run_test 271f "DoM: read on open (200K file and read tail)"
17623
17624 test_272a() {
17625         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17626                 skip "Need MDS version at least 2.11.50"
17627
17628         local dom=$DIR/$tdir/dom
17629         mkdir -p $DIR/$tdir
17630
17631         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
17632         dd if=/dev/urandom of=$dom bs=512K count=1 ||
17633                 error "failed to write data into $dom"
17634         local old_md5=$(md5sum $dom)
17635
17636         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
17637                 error "failed to migrate to the same DoM component"
17638
17639         local new_md5=$(md5sum $dom)
17640
17641         [ "$old_md5" == "$new_md5" ] ||
17642                 error "md5sum differ: $old_md5, $new_md5"
17643
17644         [ $($LFS getstripe -c $dom) -eq 2 ] ||
17645                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
17646 }
17647 run_test 272a "DoM migration: new layout with the same DOM component"
17648
17649 test_272b() {
17650         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17651                 skip "Need MDS version at least 2.11.50"
17652
17653         local dom=$DIR/$tdir/dom
17654         mkdir -p $DIR/$tdir
17655         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
17656
17657         local mdtidx=$($LFS getstripe -m $dom)
17658         local mdtname=MDT$(printf %04x $mdtidx)
17659         local facet=mds$((mdtidx + 1))
17660
17661         local mdtfree1=$(do_facet $facet \
17662                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17663         dd if=/dev/urandom of=$dom bs=2M count=1 ||
17664                 error "failed to write data into $dom"
17665         local old_md5=$(md5sum $dom)
17666         cancel_lru_locks mdc
17667         local mdtfree1=$(do_facet $facet \
17668                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17669
17670         $LFS migrate -c2 $dom ||
17671                 error "failed to migrate to the new composite layout"
17672         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
17673                 error "MDT stripe was not removed"
17674
17675         cancel_lru_locks mdc
17676         local new_md5=$(md5sum $dom)
17677         [ "$old_md5" != "$new_md5" ] &&
17678                 error "$old_md5 != $new_md5"
17679
17680         # Skip free space checks with ZFS
17681         if [ "$(facet_fstype $facet)" != "zfs" ]; then
17682                 local mdtfree2=$(do_facet $facet \
17683                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17684                 [ $mdtfree2 -gt $mdtfree1 ] ||
17685                         error "MDT space is not freed after migration"
17686         fi
17687         return 0
17688 }
17689 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
17690
17691 test_272c() {
17692         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17693                 skip "Need MDS version at least 2.11.50"
17694
17695         local dom=$DIR/$tdir/$tfile
17696         mkdir -p $DIR/$tdir
17697         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
17698
17699         local mdtidx=$($LFS getstripe -m $dom)
17700         local mdtname=MDT$(printf %04x $mdtidx)
17701         local facet=mds$((mdtidx + 1))
17702
17703         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
17704                 error "failed to write data into $dom"
17705         local old_md5=$(md5sum $dom)
17706         cancel_lru_locks mdc
17707         local mdtfree1=$(do_facet $facet \
17708                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17709
17710         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
17711                 error "failed to migrate to the new composite layout"
17712         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
17713                 error "MDT stripe was not removed"
17714
17715         cancel_lru_locks mdc
17716         local new_md5=$(md5sum $dom)
17717         [ "$old_md5" != "$new_md5" ] &&
17718                 error "$old_md5 != $new_md5"
17719
17720         # Skip free space checks with ZFS
17721         if [ "$(facet_fstype $facet)" != "zfs" ]; then
17722                 local mdtfree2=$(do_facet $facet \
17723                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17724                 [ $mdtfree2 -gt $mdtfree1 ] ||
17725                         error "MDS space is not freed after migration"
17726         fi
17727         return 0
17728 }
17729 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
17730
17731 test_273a() {
17732         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17733                 skip "Need MDS version at least 2.11.50"
17734
17735         # Layout swap cannot be done if either file has DOM component,
17736         # this will never be supported, migration should be used instead
17737
17738         local dom=$DIR/$tdir/$tfile
17739         mkdir -p $DIR/$tdir
17740
17741         $LFS setstripe -c2 ${dom}_plain
17742         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
17743         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
17744                 error "can swap layout with DoM component"
17745         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
17746                 error "can swap layout with DoM component"
17747
17748         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
17749         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
17750                 error "can swap layout with DoM component"
17751         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
17752                 error "can swap layout with DoM component"
17753         return 0
17754 }
17755 run_test 273a "DoM: layout swapping should fail with DOM"
17756
17757 test_275() {
17758         remote_ost_nodsh && skip "remote OST with nodsh"
17759         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
17760                 skip "Need OST version >= 2.10.57"
17761
17762         local file=$DIR/$tfile
17763         local oss
17764
17765         oss=$(comma_list $(osts_nodes))
17766
17767         dd if=/dev/urandom of=$file bs=1M count=2 ||
17768                 error "failed to create a file"
17769         cancel_lru_locks osc
17770
17771         #lock 1
17772         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
17773                 error "failed to read a file"
17774
17775 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
17776         $LCTL set_param fail_loc=0x8000031f
17777
17778         cancel_lru_locks osc &
17779         sleep 1
17780
17781 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
17782         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
17783         #IO takes another lock, but matches the PENDING one
17784         #and places it to the IO RPC
17785         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
17786                 error "failed to read a file with PENDING lock"
17787 }
17788 run_test 275 "Read on a canceled duplicate lock"
17789
17790 test_276() {
17791         remote_ost_nodsh && skip "remote OST with nodsh"
17792         local pid
17793
17794         do_facet ost1 "(while true; do \
17795                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
17796                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
17797         pid=$!
17798
17799         for LOOP in $(seq 20); do
17800                 stop ost1
17801                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
17802         done
17803         kill -9 $pid
17804         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
17805                 rm $TMP/sanity_276_pid"
17806 }
17807 run_test 276 "Race between mount and obd_statfs"
17808
17809 cleanup_test_300() {
17810         trap 0
17811         umask $SAVE_UMASK
17812 }
17813 test_striped_dir() {
17814         local mdt_index=$1
17815         local stripe_count
17816         local stripe_index
17817
17818         mkdir -p $DIR/$tdir
17819
17820         SAVE_UMASK=$(umask)
17821         trap cleanup_test_300 RETURN EXIT
17822
17823         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
17824                                                 $DIR/$tdir/striped_dir ||
17825                 error "set striped dir error"
17826
17827         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
17828         [ "$mode" = "755" ] || error "expect 755 got $mode"
17829
17830         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
17831                 error "getdirstripe failed"
17832         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
17833         if [ "$stripe_count" != "2" ]; then
17834                 error "1:stripe_count is $stripe_count, expect 2"
17835         fi
17836         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
17837         if [ "$stripe_count" != "2" ]; then
17838                 error "2:stripe_count is $stripe_count, expect 2"
17839         fi
17840
17841         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
17842         if [ "$stripe_index" != "$mdt_index" ]; then
17843                 error "stripe_index is $stripe_index, expect $mdt_index"
17844         fi
17845
17846         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
17847                 error "nlink error after create striped dir"
17848
17849         mkdir $DIR/$tdir/striped_dir/a
17850         mkdir $DIR/$tdir/striped_dir/b
17851
17852         stat $DIR/$tdir/striped_dir/a ||
17853                 error "create dir under striped dir failed"
17854         stat $DIR/$tdir/striped_dir/b ||
17855                 error "create dir under striped dir failed"
17856
17857         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
17858                 error "nlink error after mkdir"
17859
17860         rmdir $DIR/$tdir/striped_dir/a
17861         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
17862                 error "nlink error after rmdir"
17863
17864         rmdir $DIR/$tdir/striped_dir/b
17865         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
17866                 error "nlink error after rmdir"
17867
17868         chattr +i $DIR/$tdir/striped_dir
17869         createmany -o $DIR/$tdir/striped_dir/f 10 &&
17870                 error "immutable flags not working under striped dir!"
17871         chattr -i $DIR/$tdir/striped_dir
17872
17873         rmdir $DIR/$tdir/striped_dir ||
17874                 error "rmdir striped dir error"
17875
17876         cleanup_test_300
17877
17878         true
17879 }
17880
17881 test_300a() {
17882         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17883                 skip "skipped for lustre < 2.7.0"
17884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17885         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17886
17887         test_striped_dir 0 || error "failed on striped dir on MDT0"
17888         test_striped_dir 1 || error "failed on striped dir on MDT0"
17889 }
17890 run_test 300a "basic striped dir sanity test"
17891
17892 test_300b() {
17893         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17894                 skip "skipped for lustre < 2.7.0"
17895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17896         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17897
17898         local i
17899         local mtime1
17900         local mtime2
17901         local mtime3
17902
17903         test_mkdir $DIR/$tdir || error "mkdir fail"
17904         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
17905                 error "set striped dir error"
17906         for i in {0..9}; do
17907                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
17908                 sleep 1
17909                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
17910                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
17911                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
17912                 sleep 1
17913                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
17914                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
17915                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
17916         done
17917         true
17918 }
17919 run_test 300b "check ctime/mtime for striped dir"
17920
17921 test_300c() {
17922         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17923                 skip "skipped for lustre < 2.7.0"
17924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17925         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17926
17927         local file_count
17928
17929         mkdir -p $DIR/$tdir
17930         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
17931                 error "set striped dir error"
17932
17933         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
17934                 error "chown striped dir failed"
17935
17936         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
17937                 error "create 5k files failed"
17938
17939         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
17940
17941         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
17942
17943         rm -rf $DIR/$tdir
17944 }
17945 run_test 300c "chown && check ls under striped directory"
17946
17947 test_300d() {
17948         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17949                 skip "skipped for lustre < 2.7.0"
17950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17951         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17952
17953         local stripe_count
17954         local file
17955
17956         mkdir -p $DIR/$tdir
17957         $LFS setstripe -c 2 $DIR/$tdir
17958
17959         #local striped directory
17960         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
17961                 error "set striped dir error"
17962         createmany -o $DIR/$tdir/striped_dir/f 10 ||
17963                 error "create 10 files failed"
17964
17965         #remote striped directory
17966         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
17967                 error "set striped dir error"
17968         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
17969                 error "create 10 files failed"
17970
17971         for file in $(find $DIR/$tdir); do
17972                 stripe_count=$($LFS getstripe -c $file)
17973                 [ $stripe_count -eq 2 ] ||
17974                         error "wrong stripe $stripe_count for $file"
17975         done
17976
17977         rm -rf $DIR/$tdir
17978 }
17979 run_test 300d "check default stripe under striped directory"
17980
17981 test_300e() {
17982         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
17983                 skip "Need MDS version at least 2.7.55"
17984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17985         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17986
17987         local stripe_count
17988         local file
17989
17990         mkdir -p $DIR/$tdir
17991
17992         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
17993                 error "set striped dir error"
17994
17995         touch $DIR/$tdir/striped_dir/a
17996         touch $DIR/$tdir/striped_dir/b
17997         touch $DIR/$tdir/striped_dir/c
17998
17999         mkdir $DIR/$tdir/striped_dir/dir_a
18000         mkdir $DIR/$tdir/striped_dir/dir_b
18001         mkdir $DIR/$tdir/striped_dir/dir_c
18002
18003         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
18004                 error "set striped adir under striped dir error"
18005
18006         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
18007                 error "set striped bdir under striped dir error"
18008
18009         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
18010                 error "set striped cdir under striped dir error"
18011
18012         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
18013                 error "rename dir under striped dir fails"
18014
18015         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
18016                 error "rename dir under different stripes fails"
18017
18018         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
18019                 error "rename file under striped dir should succeed"
18020
18021         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
18022                 error "rename dir under striped dir should succeed"
18023
18024         rm -rf $DIR/$tdir
18025 }
18026 run_test 300e "check rename under striped directory"
18027
18028 test_300f() {
18029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18030         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18031         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18032                 skip "Need MDS version at least 2.7.55"
18033
18034         local stripe_count
18035         local file
18036
18037         rm -rf $DIR/$tdir
18038         mkdir -p $DIR/$tdir
18039
18040         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18041                 error "set striped dir error"
18042
18043         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
18044                 error "set striped dir error"
18045
18046         touch $DIR/$tdir/striped_dir/a
18047         mkdir $DIR/$tdir/striped_dir/dir_a
18048         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
18049                 error "create striped dir under striped dir fails"
18050
18051         touch $DIR/$tdir/striped_dir1/b
18052         mkdir $DIR/$tdir/striped_dir1/dir_b
18053         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
18054                 error "create striped dir under striped dir fails"
18055
18056         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
18057                 error "rename dir under different striped dir should fail"
18058
18059         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
18060                 error "rename striped dir under diff striped dir should fail"
18061
18062         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
18063                 error "rename file under diff striped dirs fails"
18064
18065         rm -rf $DIR/$tdir
18066 }
18067 run_test 300f "check rename cross striped directory"
18068
18069 test_300_check_default_striped_dir()
18070 {
18071         local dirname=$1
18072         local default_count=$2
18073         local default_index=$3
18074         local stripe_count
18075         local stripe_index
18076         local dir_stripe_index
18077         local dir
18078
18079         echo "checking $dirname $default_count $default_index"
18080         $LFS setdirstripe -D -c $default_count -i $default_index \
18081                                 -t all_char $DIR/$tdir/$dirname ||
18082                 error "set default stripe on striped dir error"
18083         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
18084         [ $stripe_count -eq $default_count ] ||
18085                 error "expect $default_count get $stripe_count for $dirname"
18086
18087         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
18088         [ $stripe_index -eq $default_index ] ||
18089                 error "expect $default_index get $stripe_index for $dirname"
18090
18091         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
18092                                                 error "create dirs failed"
18093
18094         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
18095         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
18096         for dir in $(find $DIR/$tdir/$dirname/*); do
18097                 stripe_count=$($LFS getdirstripe -c $dir)
18098                 [ $stripe_count -eq $default_count ] ||
18099                 [ $stripe_count -eq 0 -o $default_count -eq 1 ] ||
18100                 error "stripe count $default_count != $stripe_count for $dir"
18101
18102                 stripe_index=$($LFS getdirstripe -i $dir)
18103                 [ $default_index -eq -1 -o $stripe_index -eq $default_index ] ||
18104                         error "$stripe_index != $default_index for $dir"
18105
18106                 #check default stripe
18107                 stripe_count=$($LFS getdirstripe -D -c $dir)
18108                 [ $stripe_count -eq $default_count ] ||
18109                 error "default count $default_count != $stripe_count for $dir"
18110
18111                 stripe_index=$($LFS getdirstripe -D -i $dir)
18112                 [ $stripe_index -eq $default_index ] ||
18113                 error "default index $default_index != $stripe_index for $dir"
18114         done
18115         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
18116 }
18117
18118 test_300g() {
18119         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18120         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18121                 skip "Need MDS version at least 2.7.55"
18122
18123         local dir
18124         local stripe_count
18125         local stripe_index
18126
18127         mkdir $DIR/$tdir
18128         mkdir $DIR/$tdir/normal_dir
18129
18130         #Checking when client cache stripe index
18131         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
18132         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
18133                 error "create striped_dir failed"
18134
18135         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
18136                 error "create dir0 fails"
18137         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
18138         [ $stripe_index -eq 0 ] ||
18139                 error "dir0 expect index 0 got $stripe_index"
18140
18141         mkdir $DIR/$tdir/striped_dir/dir1 ||
18142                 error "create dir1 fails"
18143         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
18144         [ $stripe_index -eq 1 ] ||
18145                 error "dir1 expect index 1 got $stripe_index"
18146
18147         #check default stripe count/stripe index
18148         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
18149         test_300_check_default_striped_dir normal_dir 1 0
18150         test_300_check_default_striped_dir normal_dir 2 1
18151         test_300_check_default_striped_dir normal_dir 2 -1
18152
18153         #delete default stripe information
18154         echo "delete default stripeEA"
18155         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
18156                 error "set default stripe on striped dir error"
18157
18158         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
18159         for dir in $(find $DIR/$tdir/normal_dir/*); do
18160                 stripe_count=$($LFS getdirstripe -c $dir)
18161                 [ $stripe_count -eq 0 ] ||
18162                         error "expect 1 get $stripe_count for $dir"
18163                 stripe_index=$($LFS getdirstripe -i $dir)
18164                 [ $stripe_index -eq 0 ] ||
18165                         error "expect 0 get $stripe_index for $dir"
18166         done
18167 }
18168 run_test 300g "check default striped directory for normal directory"
18169
18170 test_300h() {
18171         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18172         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18173                 skip "Need MDS version at least 2.7.55"
18174
18175         local dir
18176         local stripe_count
18177
18178         mkdir $DIR/$tdir
18179         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18180                 error "set striped dir error"
18181
18182         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
18183         test_300_check_default_striped_dir striped_dir 1 0
18184         test_300_check_default_striped_dir striped_dir 2 1
18185         test_300_check_default_striped_dir striped_dir 2 -1
18186
18187         #delete default stripe information
18188         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
18189                 error "set default stripe on striped dir error"
18190
18191         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
18192         for dir in $(find $DIR/$tdir/striped_dir/*); do
18193                 stripe_count=$($LFS getdirstripe -c $dir)
18194                 [ $stripe_count -eq 0 ] ||
18195                         error "expect 1 get $stripe_count for $dir"
18196         done
18197 }
18198 run_test 300h "check default striped directory for striped directory"
18199
18200 test_300i() {
18201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18202         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18203         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18204                 skip "Need MDS version at least 2.7.55"
18205
18206         local stripe_count
18207         local file
18208
18209         mkdir $DIR/$tdir
18210
18211         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18212                 error "set striped dir error"
18213
18214         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18215                 error "create files under striped dir failed"
18216
18217         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
18218                 error "set striped hashdir error"
18219
18220         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
18221                 error "create dir0 under hash dir failed"
18222         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
18223                 error "create dir1 under hash dir failed"
18224
18225         # unfortunately, we need to umount to clear dir layout cache for now
18226         # once we fully implement dir layout, we can drop this
18227         umount_client $MOUNT || error "umount failed"
18228         mount_client $MOUNT || error "mount failed"
18229
18230         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
18231         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
18232         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
18233
18234         #set the stripe to be unknown hash type
18235         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
18236         $LCTL set_param fail_loc=0x1901
18237         for ((i = 0; i < 10; i++)); do
18238                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
18239                         error "stat f-$i failed"
18240                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
18241         done
18242
18243         touch $DIR/$tdir/striped_dir/f0 &&
18244                 error "create under striped dir with unknown hash should fail"
18245
18246         $LCTL set_param fail_loc=0
18247
18248         umount_client $MOUNT || error "umount failed"
18249         mount_client $MOUNT || error "mount failed"
18250
18251         return 0
18252 }
18253 run_test 300i "client handle unknown hash type striped directory"
18254
18255 test_300j() {
18256         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18258         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18259                 skip "Need MDS version at least 2.7.55"
18260
18261         local stripe_count
18262         local file
18263
18264         mkdir $DIR/$tdir
18265
18266         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
18267         $LCTL set_param fail_loc=0x1702
18268         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18269                 error "set striped dir error"
18270
18271         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18272                 error "create files under striped dir failed"
18273
18274         $LCTL set_param fail_loc=0
18275
18276         rm -rf $DIR/$tdir || error "unlink striped dir fails"
18277
18278         return 0
18279 }
18280 run_test 300j "test large update record"
18281
18282 test_300k() {
18283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18284         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18285         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18286                 skip "Need MDS version at least 2.7.55"
18287
18288         # this test needs a huge transaction
18289         local kb
18290         kb=$(do_facet $SINGLEMDS lctl get_param -n osd*.lustre-MDT0000.kbytestotal)
18291         [ $kb -lt $((1024*1024)) ] && skip "too small mds: $kb"
18292
18293         local stripe_count
18294         local file
18295
18296         mkdir $DIR/$tdir
18297
18298         #define OBD_FAIL_LARGE_STRIPE   0x1703
18299         $LCTL set_param fail_loc=0x1703
18300         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
18301                 error "set striped dir error"
18302         $LCTL set_param fail_loc=0
18303
18304         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18305                 error "getstripeddir fails"
18306         rm -rf $DIR/$tdir/striped_dir ||
18307                 error "unlink striped dir fails"
18308
18309         return 0
18310 }
18311 run_test 300k "test large striped directory"
18312
18313 test_300l() {
18314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18315         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18316         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18317                 skip "Need MDS version at least 2.7.55"
18318
18319         local stripe_index
18320
18321         test_mkdir -p $DIR/$tdir/striped_dir
18322         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
18323                         error "chown $RUNAS_ID failed"
18324         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
18325                 error "set default striped dir failed"
18326
18327         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
18328         $LCTL set_param fail_loc=0x80000158
18329         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
18330
18331         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
18332         [ $stripe_index -eq 1 ] ||
18333                 error "expect 1 get $stripe_index for $dir"
18334 }
18335 run_test 300l "non-root user to create dir under striped dir with stale layout"
18336
18337 test_300m() {
18338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18339         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
18340         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18341                 skip "Need MDS version at least 2.7.55"
18342
18343         mkdir -p $DIR/$tdir/striped_dir
18344         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
18345                 error "set default stripes dir error"
18346
18347         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
18348
18349         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
18350         [ $stripe_count -eq 0 ] ||
18351                         error "expect 0 get $stripe_count for a"
18352
18353         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
18354                 error "set default stripes dir error"
18355
18356         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
18357
18358         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
18359         [ $stripe_count -eq 0 ] ||
18360                         error "expect 0 get $stripe_count for b"
18361
18362         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
18363                 error "set default stripes dir error"
18364
18365         mkdir $DIR/$tdir/striped_dir/c &&
18366                 error "default stripe_index is invalid, mkdir c should fails"
18367
18368         rm -rf $DIR/$tdir || error "rmdir fails"
18369 }
18370 run_test 300m "setstriped directory on single MDT FS"
18371
18372 cleanup_300n() {
18373         local list=$(comma_list $(mdts_nodes))
18374
18375         trap 0
18376         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18377 }
18378
18379 test_300n() {
18380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18381         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18382         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18383                 skip "Need MDS version at least 2.7.55"
18384         remote_mds_nodsh && skip "remote MDS with nodsh"
18385
18386         local stripe_index
18387         local list=$(comma_list $(mdts_nodes))
18388
18389         trap cleanup_300n RETURN EXIT
18390         mkdir -p $DIR/$tdir
18391         chmod 777 $DIR/$tdir
18392         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
18393                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18394                 error "create striped dir succeeds with gid=0"
18395
18396         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18397         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
18398                 error "create striped dir fails with gid=-1"
18399
18400         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18401         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
18402                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18403                 error "set default striped dir succeeds with gid=0"
18404
18405
18406         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18407         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
18408                 error "set default striped dir fails with gid=-1"
18409
18410
18411         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18412         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
18413                                         error "create test_dir fails"
18414         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
18415                                         error "create test_dir1 fails"
18416         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
18417                                         error "create test_dir2 fails"
18418         cleanup_300n
18419 }
18420 run_test 300n "non-root user to create dir under striped dir with default EA"
18421
18422 test_300o() {
18423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18424         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18425         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18426                 skip "Need MDS version at least 2.7.55"
18427
18428         local numfree1
18429         local numfree2
18430
18431         mkdir -p $DIR/$tdir
18432
18433         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
18434         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
18435         if [ $numfree1 -lt 66000 -o $numfree2 -lt 66000 ]; then
18436                 skip "not enough free inodes $numfree1 $numfree2"
18437         fi
18438
18439         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
18440         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
18441         if [ $numfree1 -lt 300000 -o $numfree2 -lt 300000 ]; then
18442                 skip "not enough free space $numfree1 $numfree2"
18443         fi
18444
18445         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
18446                 error "setdirstripe fails"
18447
18448         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
18449                 error "create dirs fails"
18450
18451         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
18452         ls $DIR/$tdir/striped_dir > /dev/null ||
18453                 error "ls striped dir fails"
18454         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
18455                 error "unlink big striped dir fails"
18456 }
18457 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
18458
18459 test_300p() {
18460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18461         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18462         remote_mds_nodsh && skip "remote MDS with nodsh"
18463
18464         mkdir -p $DIR/$tdir
18465
18466         #define OBD_FAIL_OUT_ENOSPC     0x1704
18467         do_facet mds2 lctl set_param fail_loc=0x80001704
18468         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
18469                  && error "create striped directory should fail"
18470
18471         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
18472
18473         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
18474         true
18475 }
18476 run_test 300p "create striped directory without space"
18477
18478 test_300q() {
18479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18480         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18481
18482         local fd=$(free_fd)
18483         local cmd="exec $fd<$tdir"
18484         cd $DIR
18485         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
18486         eval $cmd
18487         cmd="exec $fd<&-"
18488         trap "eval $cmd" EXIT
18489         cd $tdir || error "cd $tdir fails"
18490         rmdir  ../$tdir || error "rmdir $tdir fails"
18491         mkdir local_dir && error "create dir succeeds"
18492         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
18493         eval $cmd
18494         return 0
18495 }
18496 run_test 300q "create remote directory under orphan directory"
18497
18498 test_300r() {
18499         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
18500                 skip "Need MDS version at least 2.7.55" && return
18501         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18502
18503         mkdir $DIR/$tdir
18504
18505         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
18506                 error "set striped dir error"
18507
18508         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18509                 error "getstripeddir fails"
18510
18511         local stripe_count
18512         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18513                       awk '/lmv_stripe_count:/ { print $2 }')
18514
18515         [ $MDSCOUNT -ne $stripe_count ] &&
18516                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
18517
18518         rm -rf $DIR/$tdir/striped_dir ||
18519                 error "unlink striped dir fails"
18520 }
18521 run_test 300r "test -1 striped directory"
18522
18523 prepare_remote_file() {
18524         mkdir $DIR/$tdir/src_dir ||
18525                 error "create remote source failed"
18526
18527         cp /etc/hosts $DIR/$tdir/src_dir/a ||
18528                  error "cp to remote source failed"
18529         touch $DIR/$tdir/src_dir/a
18530
18531         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
18532                 error "create remote target dir failed"
18533
18534         touch $DIR/$tdir/tgt_dir/b
18535
18536         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
18537                 error "rename dir cross MDT failed!"
18538
18539         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
18540                 error "src_child still exists after rename"
18541
18542         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
18543                 error "missing file(a) after rename"
18544
18545         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
18546                 error "diff after rename"
18547 }
18548
18549 test_310a() {
18550         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
18551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18552
18553         local remote_file=$DIR/$tdir/tgt_dir/b
18554
18555         mkdir -p $DIR/$tdir
18556
18557         prepare_remote_file || error "prepare remote file failed"
18558
18559         #open-unlink file
18560         $OPENUNLINK $remote_file $remote_file ||
18561                 error "openunlink $remote_file failed"
18562         $CHECKSTAT -a $remote_file || error "$remote_file exists"
18563 }
18564 run_test 310a "open unlink remote file"
18565
18566 test_310b() {
18567         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
18568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18569
18570         local remote_file=$DIR/$tdir/tgt_dir/b
18571
18572         mkdir -p $DIR/$tdir
18573
18574         prepare_remote_file || error "prepare remote file failed"
18575
18576         ln $remote_file $DIR/$tfile || error "link failed for remote file"
18577         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
18578         $CHECKSTAT -t file $remote_file || error "check file failed"
18579 }
18580 run_test 310b "unlink remote file with multiple links while open"
18581
18582 test_310c() {
18583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18584         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
18585
18586         local remote_file=$DIR/$tdir/tgt_dir/b
18587
18588         mkdir -p $DIR/$tdir
18589
18590         prepare_remote_file || error "prepare remote file failed"
18591
18592         ln $remote_file $DIR/$tfile || error "link failed for remote file"
18593         multiop_bg_pause $remote_file O_uc ||
18594                         error "mulitop failed for remote file"
18595         MULTIPID=$!
18596         $MULTIOP $DIR/$tfile Ouc
18597         kill -USR1 $MULTIPID
18598         wait $MULTIPID
18599 }
18600 run_test 310c "open-unlink remote file with multiple links"
18601
18602 #LU-4825
18603 test_311() {
18604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18605         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
18606         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
18607                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
18608         remote_mds_nodsh && skip "remote MDS with nodsh"
18609
18610         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
18611         local mdts=$(comma_list $(mdts_nodes))
18612
18613         mkdir -p $DIR/$tdir
18614         $LFS setstripe -i 0 -c 1 $DIR/$tdir
18615         createmany -o $DIR/$tdir/$tfile. 1000
18616
18617         # statfs data is not real time, let's just calculate it
18618         old_iused=$((old_iused + 1000))
18619
18620         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
18621                         osp.*OST0000*MDT0000.create_count")
18622         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
18623                                 osp.*OST0000*MDT0000.max_create_count")
18624         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
18625
18626         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
18627         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
18628         [ $index -ne 0 ] || error "$tfile stripe index is 0"
18629
18630         unlinkmany $DIR/$tdir/$tfile. 1000
18631
18632         do_nodes $mdts "$LCTL set_param -n \
18633                         osp.*OST0000*.max_create_count=$max_count"
18634         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
18635                 do_nodes $mdts "$LCTL set_param -n \
18636                                 osp.*OST0000*.create_count=$count"
18637         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
18638                         grep "=0" && error "create_count is zero"
18639
18640         local new_iused
18641         for i in $(seq 120); do
18642                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
18643                 # system may be too busy to destroy all objs in time, use
18644                 # a somewhat small value to not fail autotest
18645                 [ $((old_iused - new_iused)) -gt 400 ] && break
18646                 sleep 1
18647         done
18648
18649         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
18650         [ $((old_iused - new_iused)) -gt 400 ] ||
18651                 error "objs not destroyed after unlink"
18652 }
18653 run_test 311 "disable OSP precreate, and unlink should destroy objs"
18654
18655 zfs_oid_to_objid()
18656 {
18657         local ost=$1
18658         local objid=$2
18659
18660         local vdevdir=$(dirname $(facet_vdevice $ost))
18661         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
18662         local zfs_zapid=$(do_facet $ost $cmd |
18663                           grep -w "/O/0/d$((objid%32))" -C 5 |
18664                           awk '/Object/{getline; print $1}')
18665         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
18666                           awk "/$objid = /"'{printf $3}')
18667
18668         echo $zfs_objid
18669 }
18670
18671 zfs_object_blksz() {
18672         local ost=$1
18673         local objid=$2
18674
18675         local vdevdir=$(dirname $(facet_vdevice $ost))
18676         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
18677         local blksz=$(do_facet $ost $cmd $objid |
18678                       awk '/dblk/{getline; printf $4}')
18679
18680         case "${blksz: -1}" in
18681                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
18682                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
18683                 *) ;;
18684         esac
18685
18686         echo $blksz
18687 }
18688
18689 test_312() { # LU-4856
18690         remote_ost_nodsh && skip "remote OST with nodsh"
18691         [ "$ost1_FSTYPE" = "zfs" ] ||
18692                 skip_env "the test only applies to zfs"
18693
18694         local max_blksz=$(do_facet ost1 \
18695                           $ZFS get -p recordsize $(facet_device ost1) |
18696                           awk '!/VALUE/{print $3}')
18697
18698         # to make life a little bit easier
18699         $LFS mkdir -c 1 -i 0 $DIR/$tdir
18700         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18701
18702         local tf=$DIR/$tdir/$tfile
18703         touch $tf
18704         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18705
18706         # Get ZFS object id
18707         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18708         # block size change by sequential overwrite
18709         local bs
18710
18711         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
18712                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
18713
18714                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
18715                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
18716         done
18717         rm -f $tf
18718
18719         # block size change by sequential append write
18720         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
18721         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18722         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18723         local count
18724
18725         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
18726                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
18727                         oflag=sync conv=notrunc
18728
18729                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
18730                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
18731                         error "blksz error, actual $blksz, " \
18732                                 "expected: 2 * $count * $PAGE_SIZE"
18733         done
18734         rm -f $tf
18735
18736         # random write
18737         touch $tf
18738         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18739         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18740
18741         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
18742         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18743         [ $blksz -eq $PAGE_SIZE ] ||
18744                 error "blksz error: $blksz, expected: $PAGE_SIZE"
18745
18746         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
18747         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18748         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
18749
18750         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
18751         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18752         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
18753 }
18754 run_test 312 "make sure ZFS adjusts its block size by write pattern"
18755
18756 test_313() {
18757         remote_ost_nodsh && skip "remote OST with nodsh"
18758
18759         local file=$DIR/$tfile
18760
18761         rm -f $file
18762         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
18763
18764         # define OBD_FAIL_TGT_RCVD_EIO           0x720
18765         do_facet ost1 "$LCTL set_param fail_loc=0x720"
18766         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
18767                 error "write should failed"
18768         do_facet ost1 "$LCTL set_param fail_loc=0"
18769         rm -f $file
18770 }
18771 run_test 313 "io should fail after last_rcvd update fail"
18772
18773 test_314() {
18774         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
18775
18776         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
18777         do_facet ost1 "$LCTL set_param fail_loc=0x720"
18778         rm -f $DIR/$tfile
18779         wait_delete_completed
18780         do_facet ost1 "$LCTL set_param fail_loc=0"
18781 }
18782 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
18783
18784 test_315() { # LU-618
18785         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
18786
18787         local file=$DIR/$tfile
18788         rm -f $file
18789
18790         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
18791                 error "multiop file write failed"
18792         $MULTIOP $file oO_RDONLY:r4063232_c &
18793         PID=$!
18794
18795         sleep 2
18796
18797         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
18798         kill -USR1 $PID
18799
18800         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
18801         rm -f $file
18802 }
18803 run_test 315 "read should be accounted"
18804
18805 test_316() {
18806         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18807         large_xattr_enabled || skip_env "ea_inode feature disabled"
18808
18809         rm -rf $DIR/$tdir/d
18810         mkdir -p $DIR/$tdir/d
18811         chown nobody $DIR/$tdir/d
18812         touch $DIR/$tdir/d/file
18813
18814         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
18815 }
18816 run_test 316 "lfs mv"
18817
18818 test_317() {
18819         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
18820                 skip "Need MDS version at least 2.11.53"
18821         local trunc_sz
18822         local grant_blk_size
18823
18824         if [ "$(facet_fstype $facet)" == "zfs" ]; then
18825                 skip "LU-10370: no implementation for ZFS" && return
18826         fi
18827
18828         stack_trap "rm -f $DIR/$tfile" EXIT
18829         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
18830                         awk '/grant_block_size:/ { print $2; exit; }')
18831         #
18832         # Create File of size 5M. Truncate it to below size's and verify
18833         # blocks count.
18834         #
18835         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
18836                 error "Create file : $DIR/$tfile"
18837
18838         for trunc_sz in 2097152 4097 4000 509 0; do
18839                 $TRUNCATE $DIR/$tfile $trunc_sz ||
18840                         error "truncate $tfile to $trunc_sz failed"
18841                 local sz=$(stat --format=%s $DIR/$tfile)
18842                 local blk=$(stat --format=%b $DIR/$tfile)
18843                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
18844                                      grant_blk_size) * 8))
18845
18846                 if [[ $blk -ne $trunc_blk ]]; then
18847                         $(which stat) $DIR/$tfile
18848                         error "Expected Block $trunc_blk got $blk for $tfile"
18849                 fi
18850
18851                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
18852                         error "Expected Size $trunc_sz got $sz for $tfile"
18853         done
18854
18855         #
18856         # sparse file test
18857         # Create file with a hole and write actual two blocks. Block count
18858         # must be 16.
18859         #
18860         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
18861                 conv=fsync || error "Create file : $DIR/$tfile"
18862
18863         # Calculate the final truncate size.
18864         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
18865
18866         #
18867         # truncate to size $trunc_sz bytes. Strip the last block
18868         # The block count must drop to 8
18869         #
18870         $TRUNCATE $DIR/$tfile $trunc_sz ||
18871                 error "truncate $tfile to $trunc_sz failed"
18872
18873         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
18874         sz=$(stat --format=%s $DIR/$tfile)
18875         blk=$(stat --format=%b $DIR/$tfile)
18876
18877         if [[ $blk -ne $trunc_bsz ]]; then
18878                 $(which stat) $DIR/$tfile
18879                 error "Expected Block $trunc_bsz got $blk for $tfile"
18880         fi
18881
18882         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
18883                 error "Expected Size $trunc_sz got $sz for $tfile"
18884 }
18885 run_test 317 "Verify blocks get correctly update after truncate"
18886
18887 test_319() {
18888         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
18889
18890         local before=$(date +%s)
18891         local evict
18892         local mdir=$DIR/$tdir
18893         local file=$mdir/xxx
18894
18895         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
18896         touch $file
18897
18898 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
18899         $LCTL set_param fail_val=5 fail_loc=0x8000032c
18900         $LFS mv -m1 $file &
18901
18902         sleep 1
18903         dd if=$file of=/dev/null
18904         wait
18905         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
18906           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
18907
18908         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
18909 }
18910 run_test 319 "lost lease lock on migrate error"
18911
18912 test_fake_rw() {
18913         local read_write=$1
18914         if [ "$read_write" = "write" ]; then
18915                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
18916         elif [ "$read_write" = "read" ]; then
18917                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
18918         else
18919                 error "argument error"
18920         fi
18921
18922         # turn off debug for performance testing
18923         local saved_debug=$($LCTL get_param -n debug)
18924         $LCTL set_param debug=0
18925
18926         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18927
18928         # get ost1 size - lustre-OST0000
18929         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
18930         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
18931         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
18932
18933         if [ "$read_write" = "read" ]; then
18934                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
18935         fi
18936
18937         local start_time=$(date +%s.%N)
18938         $dd_cmd bs=1M count=$blocks oflag=sync ||
18939                 error "real dd $read_write error"
18940         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
18941
18942         if [ "$read_write" = "write" ]; then
18943                 rm -f $DIR/$tfile
18944         fi
18945
18946         # define OBD_FAIL_OST_FAKE_RW           0x238
18947         do_facet ost1 $LCTL set_param fail_loc=0x238
18948
18949         local start_time=$(date +%s.%N)
18950         $dd_cmd bs=1M count=$blocks oflag=sync ||
18951                 error "fake dd $read_write error"
18952         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
18953
18954         if [ "$read_write" = "write" ]; then
18955                 # verify file size
18956                 cancel_lru_locks osc
18957                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
18958                         error "$tfile size not $blocks MB"
18959         fi
18960         do_facet ost1 $LCTL set_param fail_loc=0
18961
18962         echo "fake $read_write $duration_fake vs. normal $read_write" \
18963                 "$duration in seconds"
18964         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
18965                 error_not_in_vm "fake write is slower"
18966
18967         $LCTL set_param -n debug="$saved_debug"
18968         rm -f $DIR/$tfile
18969 }
18970 test_399a() { # LU-7655 for OST fake write
18971         remote_ost_nodsh && skip "remote OST with nodsh"
18972
18973         test_fake_rw write
18974 }
18975 run_test 399a "fake write should not be slower than normal write"
18976
18977 test_399b() { # LU-8726 for OST fake read
18978         remote_ost_nodsh && skip "remote OST with nodsh"
18979         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
18980                 skip_env "ldiskfs only test"
18981         fi
18982
18983         test_fake_rw read
18984 }
18985 run_test 399b "fake read should not be slower than normal read"
18986
18987 test_400a() { # LU-1606, was conf-sanity test_74
18988         if ! which $CC > /dev/null 2>&1; then
18989                 skip_env "$CC is not installed"
18990         fi
18991
18992         local extra_flags=''
18993         local out=$TMP/$tfile
18994         local prefix=/usr/include/lustre
18995         local prog
18996
18997         if ! [[ -d $prefix ]]; then
18998                 # Assume we're running in tree and fixup the include path.
18999                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
19000                 extra_flags+=" -L$LUSTRE/utils/.lib"
19001         fi
19002
19003         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
19004                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
19005                         error "client api broken"
19006         done
19007         rm -f $out
19008 }
19009 run_test 400a "Lustre client api program can compile and link"
19010
19011 test_400b() { # LU-1606, LU-5011
19012         local header
19013         local out=$TMP/$tfile
19014         local prefix=/usr/include/linux/lustre
19015
19016         # We use a hard coded prefix so that this test will not fail
19017         # when run in tree. There are headers in lustre/include/lustre/
19018         # that are not packaged (like lustre_idl.h) and have more
19019         # complicated include dependencies (like config.h and lnet/types.h).
19020         # Since this test about correct packaging we just skip them when
19021         # they don't exist (see below) rather than try to fixup cppflags.
19022
19023         if ! which $CC > /dev/null 2>&1; then
19024                 skip_env "$CC is not installed"
19025         fi
19026
19027         for header in $prefix/*.h; do
19028                 if ! [[ -f "$header" ]]; then
19029                         continue
19030                 fi
19031
19032                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
19033                         continue # lustre_ioctl.h is internal header
19034                 fi
19035
19036                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
19037                         error "cannot compile '$header'"
19038         done
19039         rm -f $out
19040 }
19041 run_test 400b "packaged headers can be compiled"
19042
19043 test_401a() { #LU-7437
19044         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
19045         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
19046
19047         #count the number of parameters by "list_param -R"
19048         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
19049         #count the number of parameters by listing proc files
19050         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
19051         echo "proc_dirs='$proc_dirs'"
19052         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
19053         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
19054                       sort -u | wc -l)
19055
19056         [ $params -eq $procs ] ||
19057                 error "found $params parameters vs. $procs proc files"
19058
19059         # test the list_param -D option only returns directories
19060         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
19061         #count the number of parameters by listing proc directories
19062         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
19063                 sort -u | wc -l)
19064
19065         [ $params -eq $procs ] ||
19066                 error "found $params parameters vs. $procs proc files"
19067 }
19068 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
19069
19070 test_401b() {
19071         local save=$($LCTL get_param -n jobid_var)
19072         local tmp=testing
19073
19074         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
19075                 error "no error returned when setting bad parameters"
19076
19077         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
19078         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
19079
19080         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
19081         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
19082         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
19083 }
19084 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
19085
19086 test_401c() {
19087         local jobid_var_old=$($LCTL get_param -n jobid_var)
19088         local jobid_var_new
19089
19090         $LCTL set_param jobid_var= &&
19091                 error "no error returned for 'set_param a='"
19092
19093         jobid_var_new=$($LCTL get_param -n jobid_var)
19094         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19095                 error "jobid_var was changed by setting without value"
19096
19097         $LCTL set_param jobid_var &&
19098                 error "no error returned for 'set_param a'"
19099
19100         jobid_var_new=$($LCTL get_param -n jobid_var)
19101         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19102                 error "jobid_var was changed by setting without value"
19103 }
19104 run_test 401c "Verify 'lctl set_param' without value fails in either format."
19105
19106 test_401d() {
19107         local jobid_var_old=$($LCTL get_param -n jobid_var)
19108         local jobid_var_new
19109         local new_value="foo=bar"
19110
19111         $LCTL set_param jobid_var=$new_value ||
19112                 error "'set_param a=b' did not accept a value containing '='"
19113
19114         jobid_var_new=$($LCTL get_param -n jobid_var)
19115         [[ "$jobid_var_new" == "$new_value" ]] ||
19116                 error "'set_param a=b' failed on a value containing '='"
19117
19118         # Reset the jobid_var to test the other format
19119         $LCTL set_param jobid_var=$jobid_var_old
19120         jobid_var_new=$($LCTL get_param -n jobid_var)
19121         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19122                 error "failed to reset jobid_var"
19123
19124         $LCTL set_param jobid_var $new_value ||
19125                 error "'set_param a b' did not accept a value containing '='"
19126
19127         jobid_var_new=$($LCTL get_param -n jobid_var)
19128         [[ "$jobid_var_new" == "$new_value" ]] ||
19129                 error "'set_param a b' failed on a value containing '='"
19130
19131         $LCTL set_param jobid_var $jobid_var_old
19132         jobid_var_new=$($LCTL get_param -n jobid_var)
19133         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19134                 error "failed to reset jobid_var"
19135 }
19136 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
19137
19138 test_402() {
19139         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
19140         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
19141                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
19142         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
19143                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
19144                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
19145         remote_mds_nodsh && skip "remote MDS with nodsh"
19146
19147         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
19148 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
19149         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
19150         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
19151                 echo "Touch failed - OK"
19152 }
19153 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
19154
19155 test_403() {
19156         local file1=$DIR/$tfile.1
19157         local file2=$DIR/$tfile.2
19158         local tfile=$TMP/$tfile
19159
19160         rm -f $file1 $file2 $tfile
19161
19162         touch $file1
19163         ln $file1 $file2
19164
19165         # 30 sec OBD_TIMEOUT in ll_getattr()
19166         # right before populating st_nlink
19167         $LCTL set_param fail_loc=0x80001409
19168         stat -c %h $file1 > $tfile &
19169
19170         # create an alias, drop all locks and reclaim the dentry
19171         < $file2
19172         cancel_lru_locks mdc
19173         cancel_lru_locks osc
19174         sysctl -w vm.drop_caches=2
19175
19176         wait
19177
19178         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
19179
19180         rm -f $tfile $file1 $file2
19181 }
19182 run_test 403 "i_nlink should not drop to zero due to aliasing"
19183
19184 test_404() { # LU-6601
19185         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
19186                 skip "Need server version newer than 2.8.52"
19187         remote_mds_nodsh && skip "remote MDS with nodsh"
19188
19189         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
19190                 awk '/osp .*-osc-MDT/ { print $4}')
19191
19192         local osp
19193         for osp in $mosps; do
19194                 echo "Deactivate: " $osp
19195                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
19196                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19197                         awk -vp=$osp '$4 == p { print $2 }')
19198                 [ $stat = IN ] || {
19199                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19200                         error "deactivate error"
19201                 }
19202                 echo "Activate: " $osp
19203                 do_facet $SINGLEMDS $LCTL --device %$osp activate
19204                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19205                         awk -vp=$osp '$4 == p { print $2 }')
19206                 [ $stat = UP ] || {
19207                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19208                         error "activate error"
19209                 }
19210         done
19211 }
19212 run_test 404 "validate manual {de}activated works properly for OSPs"
19213
19214 test_405() {
19215         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19216         [ $MDS1_VERSION -lt $(version_code 2.6.92) -o \
19217         [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
19218                 skip "Layout swap lock is not supported"
19219         check_swap_layouts_support
19220
19221         test_mkdir $DIR/$tdir
19222         swap_lock_test -d $DIR/$tdir ||
19223                 error "One layout swap locked test failed"
19224 }
19225 run_test 405 "Various layout swap lock tests"
19226
19227 test_406() {
19228         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19229         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19230         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19232         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
19233                 skip "Need MDS version at least 2.8.50"
19234
19235         local def_stripe_size=$($LFS getstripe -S $MOUNT)
19236         local test_pool=$TESTNAME
19237
19238         if ! combined_mgs_mds ; then
19239                 mount_mgs_client
19240         fi
19241         pool_add $test_pool || error "pool_add failed"
19242         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
19243                 error "pool_add_targets failed"
19244
19245         save_layout_restore_at_exit $MOUNT
19246
19247         # parent set default stripe count only, child will stripe from both
19248         # parent and fs default
19249         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
19250                 error "setstripe $MOUNT failed"
19251         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
19252         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
19253         for i in $(seq 10); do
19254                 local f=$DIR/$tdir/$tfile.$i
19255                 touch $f || error "touch failed"
19256                 local count=$($LFS getstripe -c $f)
19257                 [ $count -eq $OSTCOUNT ] ||
19258                         error "$f stripe count $count != $OSTCOUNT"
19259                 local offset=$($LFS getstripe -i $f)
19260                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
19261                 local size=$($LFS getstripe -S $f)
19262                 [ $size -eq $((def_stripe_size * 2)) ] ||
19263                         error "$f stripe size $size != $((def_stripe_size * 2))"
19264                 local pool=$($LFS getstripe -p $f)
19265                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
19266         done
19267
19268         # change fs default striping, delete parent default striping, now child
19269         # will stripe from new fs default striping only
19270         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
19271                 error "change $MOUNT default stripe failed"
19272         $LFS setstripe -c 0 $DIR/$tdir ||
19273                 error "delete $tdir default stripe failed"
19274         for i in $(seq 11 20); do
19275                 local f=$DIR/$tdir/$tfile.$i
19276                 touch $f || error "touch $f failed"
19277                 local count=$($LFS getstripe -c $f)
19278                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
19279                 local offset=$($LFS getstripe -i $f)
19280                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
19281                 local size=$($LFS getstripe -S $f)
19282                 [ $size -eq $def_stripe_size ] ||
19283                         error "$f stripe size $size != $def_stripe_size"
19284                 local pool=$($LFS getstripe -p $f)
19285                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
19286         done
19287
19288         unlinkmany $DIR/$tdir/$tfile. 1 20
19289
19290         local f=$DIR/$tdir/$tfile
19291         pool_remove_all_targets $test_pool $f
19292         pool_remove $test_pool $f
19293
19294         if ! combined_mgs_mds ; then
19295                 umount_mgs_client
19296         fi
19297 }
19298 run_test 406 "DNE support fs default striping"
19299
19300 test_407() {
19301         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19302         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19303                 skip "Need MDS version at least 2.8.55"
19304         remote_mds_nodsh && skip "remote MDS with nodsh"
19305
19306         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
19307                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
19308         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
19309                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
19310         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
19311
19312         #define OBD_FAIL_DT_TXN_STOP    0x2019
19313         for idx in $(seq $MDSCOUNT); do
19314                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
19315         done
19316         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
19317         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
19318                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
19319         true
19320 }
19321 run_test 407 "transaction fail should cause operation fail"
19322
19323 test_408() {
19324         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
19325
19326         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
19327         lctl set_param fail_loc=0x8000040a
19328         # let ll_prepare_partial_page() fail
19329         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
19330
19331         rm -f $DIR/$tfile
19332
19333         # create at least 100 unused inodes so that
19334         # shrink_icache_memory(0) should not return 0
19335         touch $DIR/$tfile-{0..100}
19336         rm -f $DIR/$tfile-{0..100}
19337         sync
19338
19339         echo 2 > /proc/sys/vm/drop_caches
19340 }
19341 run_test 408 "drop_caches should not hang due to page leaks"
19342
19343 test_409()
19344 {
19345         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19346
19347         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
19348         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
19349         touch $DIR/$tdir/guard || error "(2) Fail to create"
19350
19351         local PREFIX=$(str_repeat 'A' 128)
19352         echo "Create 1K hard links start at $(date)"
19353         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19354                 error "(3) Fail to hard link"
19355
19356         echo "Links count should be right although linkEA overflow"
19357         stat $DIR/$tdir/guard || error "(4) Fail to stat"
19358         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
19359         [ $linkcount -eq 1001 ] ||
19360                 error "(5) Unexpected hard links count: $linkcount"
19361
19362         echo "List all links start at $(date)"
19363         ls -l $DIR/$tdir/foo > /dev/null ||
19364                 error "(6) Fail to list $DIR/$tdir/foo"
19365
19366         echo "Unlink hard links start at $(date)"
19367         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19368                 error "(7) Fail to unlink"
19369         echo "Unlink hard links finished at $(date)"
19370 }
19371 run_test 409 "Large amount of cross-MDTs hard links on the same file"
19372
19373 test_410()
19374 {
19375         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
19376                 skip "Need client version at least 2.9.59"
19377
19378         # Create a file, and stat it from the kernel
19379         local testfile=$DIR/$tfile
19380         touch $testfile
19381
19382         local run_id=$RANDOM
19383         local my_ino=$(stat --format "%i" $testfile)
19384
19385         # Try to insert the module. This will always fail as the
19386         # module is designed to not be inserted.
19387         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
19388             &> /dev/null
19389
19390         # Anything but success is a test failure
19391         dmesg | grep -q \
19392             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
19393             error "no inode match"
19394 }
19395 run_test 410 "Test inode number returned from kernel thread"
19396
19397 cleanup_test411_cgroup() {
19398         trap 0
19399         rmdir "$1"
19400 }
19401
19402 test_411() {
19403         local cg_basedir=/sys/fs/cgroup/memory
19404         # LU-9966
19405         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
19406                 skip "no setup for cgroup"
19407
19408         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
19409                 error "test file creation failed"
19410         cancel_lru_locks osc
19411
19412         # Create a very small memory cgroup to force a slab allocation error
19413         local cgdir=$cg_basedir/osc_slab_alloc
19414         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
19415         trap "cleanup_test411_cgroup $cgdir" EXIT
19416         echo 2M > $cgdir/memory.kmem.limit_in_bytes
19417         echo 1M > $cgdir/memory.limit_in_bytes
19418
19419         # Should not LBUG, just be killed by oom-killer
19420         # dd will return 0 even allocation failure in some environment.
19421         # So don't check return value
19422         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
19423         cleanup_test411_cgroup $cgdir
19424
19425         return 0
19426 }
19427 run_test 411 "Slab allocation error with cgroup does not LBUG"
19428
19429 test_412() {
19430         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19431         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19432                 skip "Need server version at least 2.10.55"
19433         fi
19434
19435         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
19436                 error "mkdir failed"
19437         $LFS getdirstripe $DIR/$tdir
19438         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19439         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
19440                 error "expect $((MDSCOUT - 1)) get $stripe_index"
19441         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
19442         [ $stripe_count -eq 2 ] ||
19443                 error "expect 2 get $stripe_count"
19444 }
19445 run_test 412 "mkdir on specific MDTs"
19446
19447 test_413() {
19448         [ $MDSCOUNT -lt 2 ] &&
19449                 skip "We need at least 2 MDTs for this test"
19450
19451         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19452                 skip "Need server version at least 2.10.55"
19453         fi
19454
19455         mkdir $DIR/$tdir || error "mkdir failed"
19456
19457         # find MDT that is the most full
19458         local max=$($LFS df | grep MDT |
19459                 awk 'BEGIN { a=0 }
19460                         { sub("%", "", $5)
19461                           if (0+$5 >= a)
19462                           {
19463                                 a = $5
19464                                 b = $6
19465                           }
19466                         }
19467                      END { split(b, c, ":")
19468                            sub("]", "", c[2])
19469                            print c[2]
19470                          }')
19471
19472         for i in $(seq $((MDSCOUNT - 1))); do
19473                 $LFS mkdir -c $i $DIR/$tdir/d$i ||
19474                         error "mkdir d$i failed"
19475                 $LFS getdirstripe $DIR/$tdir/d$i
19476                 local stripe_index=$($LFS getdirstripe -i $DIR/$tdir/d$i)
19477                 [ $stripe_index -ne $max ] ||
19478                         error "don't expect $max"
19479         done
19480 }
19481 run_test 413 "mkdir on less full MDTs"
19482
19483 test_414() {
19484 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
19485         $LCTL set_param fail_loc=0x80000521
19486         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
19487         rm -f $DIR/$tfile
19488 }
19489 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
19490
19491 test_415() {
19492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19493         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
19494                 skip "Need server version at least 2.11.52"
19495
19496         # LU-11102
19497         local total
19498         local setattr_pid
19499         local start_time
19500         local end_time
19501         local duration
19502
19503         total=500
19504         # this test may be slow on ZFS
19505         [ "$mds1_FSTYPE" == "zfs" ] && total=100
19506
19507         # though this test is designed for striped directory, let's test normal
19508         # directory too since lock is always saved as CoS lock.
19509         test_mkdir $DIR/$tdir || error "mkdir $tdir"
19510         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
19511
19512         (
19513                 while true; do
19514                         touch $DIR/$tdir
19515                 done
19516         ) &
19517         setattr_pid=$!
19518
19519         start_time=$(date +%s)
19520         for i in $(seq $total); do
19521                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
19522                         > /dev/null
19523         done
19524         end_time=$(date +%s)
19525         duration=$((end_time - start_time))
19526
19527         kill -9 $setattr_pid
19528
19529         echo "rename $total files took $duration sec"
19530         [ $duration -lt 100 ] || error "rename took $duration sec"
19531 }
19532 run_test 415 "lock revoke is not missing"
19533
19534 test_416() {
19535         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
19536                 skip "Need server version at least 2.11.55"
19537
19538         # define OBD_FAIL_OSD_TXN_START    0x19a
19539         do_facet mds1 lctl set_param fail_loc=0x19a
19540
19541         lfs mkdir -c $MDSCOUNT $DIR/$tdir
19542
19543         true
19544 }
19545 run_test 416 "transaction start failure won't cause system hung"
19546
19547 cleanup_417() {
19548         trap 0
19549         do_nodes $(comma_list $(mdts_nodes)) \
19550                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
19551         do_nodes $(comma_list $(mdts_nodes)) \
19552                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
19553         do_nodes $(comma_list $(mdts_nodes)) \
19554                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
19555 }
19556
19557 test_417() {
19558         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19559         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
19560                 skip "Need MDS version at least 2.11.56"
19561
19562         trap cleanup_417 RETURN EXIT
19563
19564         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
19565         do_nodes $(comma_list $(mdts_nodes)) \
19566                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
19567         $LFS migrate -m 0 $DIR/$tdir.1 &&
19568                 error "migrate dir $tdir.1 should fail"
19569
19570         do_nodes $(comma_list $(mdts_nodes)) \
19571                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
19572         $LFS mkdir -i 1 $DIR/$tdir.2 &&
19573                 error "create remote dir $tdir.2 should fail"
19574
19575         do_nodes $(comma_list $(mdts_nodes)) \
19576                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
19577         $LFS mkdir -c 2 $DIR/$tdir.3 &&
19578                 error "create striped dir $tdir.3 should fail"
19579         true
19580 }
19581 run_test 417 "disable remote dir, striped dir and dir migration"
19582
19583 # Checks that the outputs of df [-i] and lfs df [-i] match
19584 #
19585 # usage: check_lfs_df <blocks | inodes> <mountpoint>
19586 check_lfs_df() {
19587         local dir=$2
19588         local inodes
19589         local df_out
19590         local lfs_df_out
19591         local count
19592         local passed=false
19593
19594         # blocks or inodes
19595         [ "$1" == "blocks" ] && inodes= || inodes="-i"
19596
19597         for count in {1..100}; do
19598                 cancel_lru_locks
19599                 sync; sleep 0.2
19600
19601                 # read the lines of interest
19602                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
19603                         error "df $inodes $dir | tail -n +2 failed"
19604                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
19605                         error "lfs df $inodes $dir | grep summary: failed"
19606
19607                 # skip first substrings of each output as they are different
19608                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
19609                 # compare the two outputs
19610                 passed=true
19611                 for i in {1..5}; do
19612                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
19613                 done
19614                 $passed && break
19615         done
19616
19617         if ! $passed; then
19618                 df -P $inodes $dir
19619                 echo
19620                 lfs df $inodes $dir
19621                 error "df and lfs df $1 output mismatch: "      \
19622                       "df ${inodes}: ${df_out[*]}, "            \
19623                       "lfs df ${inodes}: ${lfs_df_out[*]}"
19624         fi
19625 }
19626
19627 test_418() {
19628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19629
19630         local dir=$DIR/$tdir
19631         local numfiles=$((RANDOM % 4096 + 2))
19632         local numblocks=$((RANDOM % 256 + 1))
19633
19634         wait_delete_completed
19635         test_mkdir $dir
19636
19637         # check block output
19638         check_lfs_df blocks $dir
19639         # check inode output
19640         check_lfs_df inodes $dir
19641
19642         # create a single file and retest
19643         echo "Creating a single file and testing"
19644         createmany -o $dir/$tfile- 1 &>/dev/null ||
19645                 error "creating 1 file in $dir failed"
19646         check_lfs_df blocks $dir
19647         check_lfs_df inodes $dir
19648
19649         # create a random number of files
19650         echo "Creating $((numfiles - 1)) files and testing"
19651         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
19652                 error "creating $((numfiles - 1)) files in $dir failed"
19653
19654         # write a random number of blocks to the first test file
19655         echo "Writing $numblocks 4K blocks and testing"
19656         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
19657                 count=$numblocks &>/dev/null ||
19658                 error "dd to $dir/${tfile}-0 failed"
19659
19660         # retest
19661         check_lfs_df blocks $dir
19662         check_lfs_df inodes $dir
19663
19664         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
19665                 error "unlinking $numfiles files in $dir failed"
19666 }
19667 run_test 418 "df and lfs df outputs match"
19668
19669 prep_801() {
19670         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
19671         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
19672                 skip "Need server version at least 2.9.55"
19673
19674         start_full_debug_logging
19675 }
19676
19677 post_801() {
19678         stop_full_debug_logging
19679 }
19680
19681 barrier_stat() {
19682         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
19683                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
19684                            awk '/The barrier for/ { print $7 }')
19685                 echo $st
19686         else
19687                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
19688                 echo \'$st\'
19689         fi
19690 }
19691
19692 barrier_expired() {
19693         local expired
19694
19695         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
19696                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
19697                           awk '/will be expired/ { print $7 }')
19698         else
19699                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
19700         fi
19701
19702         echo $expired
19703 }
19704
19705 test_801a() {
19706         prep_801
19707
19708         echo "Start barrier_freeze at: $(date)"
19709         #define OBD_FAIL_BARRIER_DELAY          0x2202
19710         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
19711         do_facet mgs $LCTL barrier_freeze $FSNAME 10 &
19712
19713         sleep 2
19714         local b_status=$(barrier_stat)
19715         echo "Got barrier status at: $(date)"
19716         [ "$b_status" = "'freezing_p1'" ] ||
19717                 error "(1) unexpected barrier status $b_status"
19718
19719         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
19720         wait
19721         b_status=$(barrier_stat)
19722         [ "$b_status" = "'frozen'" ] ||
19723                 error "(2) unexpected barrier status $b_status"
19724
19725         local expired=$(barrier_expired)
19726         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
19727         sleep $((expired + 3))
19728
19729         b_status=$(barrier_stat)
19730         [ "$b_status" = "'expired'" ] ||
19731                 error "(3) unexpected barrier status $b_status"
19732
19733         do_facet mgs $LCTL barrier_freeze $FSNAME 10 ||
19734                 error "(4) fail to freeze barrier"
19735
19736         b_status=$(barrier_stat)
19737         [ "$b_status" = "'frozen'" ] ||
19738                 error "(5) unexpected barrier status $b_status"
19739
19740         echo "Start barrier_thaw at: $(date)"
19741         #define OBD_FAIL_BARRIER_DELAY          0x2202
19742         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
19743         do_facet mgs $LCTL barrier_thaw $FSNAME &
19744
19745         sleep 2
19746         b_status=$(barrier_stat)
19747         echo "Got barrier status at: $(date)"
19748         [ "$b_status" = "'thawing'" ] ||
19749                 error "(6) unexpected barrier status $b_status"
19750
19751         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
19752         wait
19753         b_status=$(barrier_stat)
19754         [ "$b_status" = "'thawed'" ] ||
19755                 error "(7) unexpected barrier status $b_status"
19756
19757         #define OBD_FAIL_BARRIER_FAILURE        0x2203
19758         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
19759         do_facet mgs $LCTL barrier_freeze $FSNAME
19760
19761         b_status=$(barrier_stat)
19762         [ "$b_status" = "'failed'" ] ||
19763                 error "(8) unexpected barrier status $b_status"
19764
19765         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19766         do_facet mgs $LCTL barrier_thaw $FSNAME
19767
19768         post_801
19769 }
19770 run_test 801a "write barrier user interfaces and stat machine"
19771
19772 test_801b() {
19773         prep_801
19774
19775         mkdir $DIR/$tdir || error "(1) fail to mkdir"
19776         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
19777         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
19778         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
19779         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
19780
19781         cancel_lru_locks mdc
19782
19783         # 180 seconds should be long enough
19784         do_facet mgs $LCTL barrier_freeze $FSNAME 180
19785
19786         local b_status=$(barrier_stat)
19787         [ "$b_status" = "'frozen'" ] ||
19788                 error "(6) unexpected barrier status $b_status"
19789
19790         mkdir $DIR/$tdir/d0/d10 &
19791         mkdir_pid=$!
19792
19793         touch $DIR/$tdir/d1/f13 &
19794         touch_pid=$!
19795
19796         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
19797         ln_pid=$!
19798
19799         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
19800         mv_pid=$!
19801
19802         rm -f $DIR/$tdir/d4/f12 &
19803         rm_pid=$!
19804
19805         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
19806
19807         # To guarantee taht the 'stat' is not blocked
19808         b_status=$(barrier_stat)
19809         [ "$b_status" = "'frozen'" ] ||
19810                 error "(8) unexpected barrier status $b_status"
19811
19812         # let above commands to run at background
19813         sleep 5
19814
19815         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
19816         ps -p $touch_pid || error "(10) touch should be blocked"
19817         ps -p $ln_pid || error "(11) link should be blocked"
19818         ps -p $mv_pid || error "(12) rename should be blocked"
19819         ps -p $rm_pid || error "(13) unlink should be blocked"
19820
19821         b_status=$(barrier_stat)
19822         [ "$b_status" = "'frozen'" ] ||
19823                 error "(14) unexpected barrier status $b_status"
19824
19825         do_facet mgs $LCTL barrier_thaw $FSNAME
19826         b_status=$(barrier_stat)
19827         [ "$b_status" = "'thawed'" ] ||
19828                 error "(15) unexpected barrier status $b_status"
19829
19830         wait $mkdir_pid || error "(16) mkdir should succeed"
19831         wait $touch_pid || error "(17) touch should succeed"
19832         wait $ln_pid || error "(18) link should succeed"
19833         wait $mv_pid || error "(19) rename should succeed"
19834         wait $rm_pid || error "(20) unlink should succeed"
19835
19836         post_801
19837 }
19838 run_test 801b "modification will be blocked by write barrier"
19839
19840 test_801c() {
19841         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19842
19843         prep_801
19844
19845         stop mds2 || error "(1) Fail to stop mds2"
19846
19847         do_facet mgs $LCTL barrier_freeze $FSNAME 30
19848
19849         local b_status=$(barrier_stat)
19850         [ "$b_status" = "'expired'" -o "$b_status" = "'failed'" ] || {
19851                 do_facet mgs $LCTL barrier_thaw $FSNAME
19852                 error "(2) unexpected barrier status $b_status"
19853         }
19854
19855         do_facet mgs $LCTL barrier_rescan $FSNAME ||
19856                 error "(3) Fail to rescan barrier bitmap"
19857
19858         do_facet mgs $LCTL barrier_freeze $FSNAME 10
19859
19860         b_status=$(barrier_stat)
19861         [ "$b_status" = "'frozen'" ] ||
19862                 error "(4) unexpected barrier status $b_status"
19863
19864         do_facet mgs $LCTL barrier_thaw $FSNAME
19865         b_status=$(barrier_stat)
19866         [ "$b_status" = "'thawed'" ] ||
19867                 error "(5) unexpected barrier status $b_status"
19868
19869         local devname=$(mdsdevname 2)
19870
19871         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
19872
19873         do_facet mgs $LCTL barrier_rescan $FSNAME ||
19874                 error "(7) Fail to rescan barrier bitmap"
19875
19876         post_801
19877 }
19878 run_test 801c "rescan barrier bitmap"
19879
19880 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
19881 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
19882 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
19883
19884 cleanup_802a() {
19885         trap 0
19886
19887         stopall
19888         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
19889         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
19890         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
19891         setupall
19892 }
19893
19894 test_802a() {
19895
19896         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
19897         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
19898                 skip "Need server version at least 2.9.55"
19899
19900         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
19901
19902         mkdir $DIR/$tdir || error "(1) fail to mkdir"
19903
19904         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
19905                 error "(2) Fail to copy"
19906
19907         trap cleanup_802a EXIT
19908
19909         # sync by force before remount as readonly
19910         sync; sync_all_data; sleep 3; sync_all_data
19911
19912         stopall
19913
19914         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
19915         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
19916         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
19917
19918         echo "Mount the server as read only"
19919         setupall server_only || error "(3) Fail to start servers"
19920
19921         echo "Mount client without ro should fail"
19922         mount_client $MOUNT &&
19923                 error "(4) Mount client without 'ro' should fail"
19924
19925         echo "Mount client with ro should succeed"
19926         mount_client $MOUNT ro ||
19927                 error "(5) Mount client with 'ro' should succeed"
19928
19929         echo "Modify should be refused"
19930         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
19931
19932         echo "Read should be allowed"
19933         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
19934                 error "(7) Read should succeed under ro mode"
19935
19936         cleanup_802a
19937 }
19938 run_test 802a "simulate readonly device"
19939
19940 test_802b() {
19941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19942         remote_mds_nodsh && skip "remote MDS with nodsh"
19943
19944         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
19945                 skip "readonly option not available"
19946
19947         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
19948
19949         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
19950                 error "(2) Fail to copy"
19951
19952         # write back all cached data before setting MDT to readonly
19953         cancel_lru_locks
19954         sync_all_data
19955
19956         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
19957         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
19958
19959         echo "Modify should be refused"
19960         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
19961
19962         echo "Read should be allowed"
19963         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
19964                 error "(7) Read should succeed under ro mode"
19965
19966         # disable readonly
19967         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
19968 }
19969 run_test 802b "be able to set MDTs to readonly"
19970
19971 test_803() {
19972         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19973         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
19974                 skip "MDS needs to be newer than 2.10.54"
19975
19976         mkdir -p $DIR/$tdir
19977         # Create some objects on all MDTs to trigger related logs objects
19978         for idx in $(seq $MDSCOUNT); do
19979                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
19980                         $DIR/$tdir/dir${idx} ||
19981                         error "Fail to create $DIR/$tdir/dir${idx}"
19982         done
19983
19984         sync; sleep 3
19985         wait_delete_completed # ensure old test cleanups are finished
19986         echo "before create:"
19987         $LFS df -i $MOUNT
19988         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
19989
19990         for i in {1..10}; do
19991                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
19992                         error "Fail to create $DIR/$tdir/foo$i"
19993         done
19994
19995         sync; sleep 3
19996         echo "after create:"
19997         $LFS df -i $MOUNT
19998         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
19999
20000         # allow for an llog to be cleaned up during the test
20001         [ $after_used -ge $((before_used + 10 - 1)) ] ||
20002                 error "before ($before_used) + 10 > after ($after_used)"
20003
20004         for i in {1..10}; do
20005                 rm -rf $DIR/$tdir/foo$i ||
20006                         error "Fail to remove $DIR/$tdir/foo$i"
20007         done
20008
20009         sleep 3 # avoid MDT return cached statfs
20010         wait_delete_completed
20011         echo "after unlink:"
20012         $LFS df -i $MOUNT
20013         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20014
20015         # allow for an llog to be created during the test
20016         [ $after_used -le $((before_used + 1)) ] ||
20017                 error "after ($after_used) > before ($before_used) + 1"
20018 }
20019 run_test 803 "verify agent object for remote object"
20020
20021 test_804() {
20022         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20023         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
20024                 skip "MDS needs to be newer than 2.10.54"
20025         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20026
20027         mkdir -p $DIR/$tdir
20028         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
20029                 error "Fail to create $DIR/$tdir/dir0"
20030
20031         local fid=$($LFS path2fid $DIR/$tdir/dir0)
20032         local dev=$(mdsdevname 2)
20033
20034         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20035                 grep ${fid} || error "NOT found agent entry for dir0"
20036
20037         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
20038                 error "Fail to create $DIR/$tdir/dir1"
20039
20040         touch $DIR/$tdir/dir1/foo0 ||
20041                 error "Fail to create $DIR/$tdir/dir1/foo0"
20042         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
20043         local rc=0
20044
20045         for idx in $(seq $MDSCOUNT); do
20046                 dev=$(mdsdevname $idx)
20047                 do_facet mds${idx} \
20048                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20049                         grep ${fid} && rc=$idx
20050         done
20051
20052         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
20053                 error "Fail to rename foo0 to foo1"
20054         if [ $rc -eq 0 ]; then
20055                 for idx in $(seq $MDSCOUNT); do
20056                         dev=$(mdsdevname $idx)
20057                         do_facet mds${idx} \
20058                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20059                         grep ${fid} && rc=$idx
20060                 done
20061         fi
20062
20063         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
20064                 error "Fail to rename foo1 to foo2"
20065         if [ $rc -eq 0 ]; then
20066                 for idx in $(seq $MDSCOUNT); do
20067                         dev=$(mdsdevname $idx)
20068                         do_facet mds${idx} \
20069                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20070                         grep ${fid} && rc=$idx
20071                 done
20072         fi
20073
20074         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
20075
20076         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
20077                 error "Fail to link to $DIR/$tdir/dir1/foo2"
20078         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
20079                 error "Fail to rename foo2 to foo0"
20080         unlink $DIR/$tdir/dir1/foo0 ||
20081                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
20082         rm -rf $DIR/$tdir/dir0 ||
20083                 error "Fail to rm $DIR/$tdir/dir0"
20084
20085         for idx in $(seq $MDSCOUNT); do
20086                 dev=$(mdsdevname $idx)
20087                 rc=0
20088
20089                 stop mds${idx}
20090                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
20091                         rc=$?
20092                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
20093                         error "mount mds$idx failed"
20094                 df $MOUNT > /dev/null 2>&1
20095
20096                 # e2fsck should not return error
20097                 [ $rc -eq 0 ] ||
20098                         error "e2fsck detected error on MDT${idx}: rc=$rc"
20099         done
20100 }
20101 run_test 804 "verify agent entry for remote entry"
20102
20103 cleanup_805() {
20104         do_facet $SINGLEMDS zfs set quota=$old $fsset
20105         unlinkmany $DIR/$tdir/f- 1000000
20106         trap 0
20107 }
20108
20109 test_805() {
20110         local zfs_version=$(do_node $SINGLEMDS cat /sys/module/zfs/version)
20111         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
20112         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
20113                 skip "netfree not implemented before 0.7"
20114         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
20115                 skip "Need MDS version at least 2.10.57"
20116
20117         local fsset
20118         local freekb
20119         local usedkb
20120         local old
20121         local quota
20122         local pref="osd-zfs.lustre-MDT0000."
20123
20124         # limit available space on MDS dataset to meet nospace issue
20125         # quickly. then ZFS 0.7.2 can use reserved space if asked
20126         # properly (using netfree flag in osd_declare_destroy()
20127         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
20128         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
20129                 gawk '{print $3}')
20130         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
20131         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
20132         let "usedkb=usedkb-freekb"
20133         let "freekb=freekb/2"
20134         if let "freekb > 5000"; then
20135                 let "freekb=5000"
20136         fi
20137         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
20138         trap cleanup_805 EXIT
20139         mkdir $DIR/$tdir
20140         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
20141         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
20142         rm -rf $DIR/$tdir || error "not able to remove"
20143         do_facet $SINGLEMDS zfs set quota=$old $fsset
20144         trap 0
20145 }
20146 run_test 805 "ZFS can remove from full fs"
20147
20148 # Size-on-MDS test
20149 check_lsom_data()
20150 {
20151         local file=$1
20152         local size=$($LFS getsom -s $file)
20153         local expect=$(stat -c %s $file)
20154
20155         [[ $size == $expect ]] ||
20156                 error "$file expected size: $expect, got: $size"
20157
20158         local blocks=$($LFS getsom -b $file)
20159         expect=$(stat -c %b $file)
20160         [[ $blocks == $expect ]] ||
20161                 error "$file expected blocks: $expect, got: $blocks"
20162 }
20163
20164 check_lsom_size()
20165 {
20166         local size=$($LFS getsom -s $1)
20167         local expect=$2
20168
20169         [[ $size == $expect ]] ||
20170                 error "$file expected size: $expect, got: $size"
20171 }
20172
20173 test_806() {
20174         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20175                 skip "Need MDS version at least 2.11.52"
20176
20177         local bs=1048576
20178
20179         touch $DIR/$tfile || error "touch $tfile failed"
20180
20181         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20182         save_lustre_params client "llite.*.xattr_cache" > $save
20183         lctl set_param llite.*.xattr_cache=0
20184         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20185
20186         # single-threaded write
20187         echo "Test SOM for single-threaded write"
20188         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
20189                 error "write $tfile failed"
20190         check_lsom_size $DIR/$tfile $bs
20191
20192         local num=32
20193         local size=$(($num * $bs))
20194         local offset=0
20195         local i
20196
20197         echo "Test SOM for single client multi-threaded($num) write"
20198         $TRUNCATE $DIR/$tfile 0
20199         for ((i = 0; i < $num; i++)); do
20200                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20201                 local pids[$i]=$!
20202                 offset=$((offset + $bs))
20203         done
20204         for (( i=0; i < $num; i++ )); do
20205                 wait ${pids[$i]}
20206         done
20207         check_lsom_size $DIR/$tfile $size
20208
20209         $TRUNCATE $DIR/$tfile 0
20210         for ((i = 0; i < $num; i++)); do
20211                 offset=$((offset - $bs))
20212                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20213                 local pids[$i]=$!
20214         done
20215         for (( i=0; i < $num; i++ )); do
20216                 wait ${pids[$i]}
20217         done
20218         check_lsom_size $DIR/$tfile $size
20219
20220         # multi-client wirtes
20221         num=$(get_node_count ${CLIENTS//,/ })
20222         size=$(($num * $bs))
20223         offset=0
20224         i=0
20225
20226         echo "Test SOM for multi-client ($num) writes"
20227         $TRUNCATE $DIR/$tfile 0
20228         for client in ${CLIENTS//,/ }; do
20229                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20230                 local pids[$i]=$!
20231                 i=$((i + 1))
20232                 offset=$((offset + $bs))
20233         done
20234         for (( i=0; i < $num; i++ )); do
20235                 wait ${pids[$i]}
20236         done
20237         check_lsom_size $DIR/$tfile $offset
20238
20239         i=0
20240         $TRUNCATE $DIR/$tfile 0
20241         for client in ${CLIENTS//,/ }; do
20242                 offset=$((offset - $bs))
20243                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20244                 local pids[$i]=$!
20245                 i=$((i + 1))
20246         done
20247         for (( i=0; i < $num; i++ )); do
20248                 wait ${pids[$i]}
20249         done
20250         check_lsom_size $DIR/$tfile $size
20251
20252         # verify truncate
20253         echo "Test SOM for truncate"
20254         $TRUNCATE $DIR/$tfile 1048576
20255         check_lsom_size $DIR/$tfile 1048576
20256         $TRUNCATE $DIR/$tfile 1234
20257         check_lsom_size $DIR/$tfile 1234
20258
20259         # verify SOM blocks count
20260         echo "Verify SOM block count"
20261         $TRUNCATE $DIR/$tfile 0
20262         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
20263                 error "failed to write file $tfile"
20264         check_lsom_data $DIR/$tfile
20265 }
20266 run_test 806 "Verify Lazy Size on MDS"
20267
20268 test_807() {
20269         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
20270         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20271                 skip "Need MDS version at least 2.11.52"
20272
20273         # Registration step
20274         changelog_register || error "changelog_register failed"
20275         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
20276         changelog_users $SINGLEMDS | grep -q $cl_user ||
20277                 error "User $cl_user not found in changelog_users"
20278
20279         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20280         save_lustre_params client "llite.*.xattr_cache" > $save
20281         lctl set_param llite.*.xattr_cache=0
20282         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20283
20284         rm -rf $DIR/$tdir || error "rm $tdir failed"
20285         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
20286         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
20287         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
20288         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
20289                 error "truncate $tdir/trunc failed"
20290
20291         local bs=1048576
20292         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
20293                 error "write $tfile failed"
20294
20295         # multi-client wirtes
20296         local num=$(get_node_count ${CLIENTS//,/ })
20297         local offset=0
20298         local i=0
20299
20300         echo "Test SOM for multi-client ($num) writes"
20301         touch $DIR/$tfile || error "touch $tfile failed"
20302         $TRUNCATE $DIR/$tfile 0
20303         for client in ${CLIENTS//,/ }; do
20304                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20305                 local pids[$i]=$!
20306                 i=$((i + 1))
20307                 offset=$((offset + $bs))
20308         done
20309         for (( i=0; i < $num; i++ )); do
20310                 wait ${pids[$i]}
20311         done
20312
20313         sleep 5
20314         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
20315         check_lsom_data $DIR/$tdir/trunc
20316         check_lsom_data $DIR/$tdir/single_dd
20317         check_lsom_data $DIR/$tfile
20318
20319         rm -rf $DIR/$tdir
20320         # Deregistration step
20321         changelog_deregister || error "changelog_deregister failed"
20322 }
20323 run_test 807 "verify LSOM syncing tool"
20324
20325 check_som_nologged()
20326 {
20327         local lines=$($LFS changelog $FSNAME-MDT0000 |
20328                 grep 'x=trusted.som' | wc -l)
20329         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
20330 }
20331
20332 test_808() {
20333         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
20334                 skip "Need MDS version at least 2.11.55"
20335
20336         # Registration step
20337         changelog_register || error "changelog_register failed"
20338
20339         touch $DIR/$tfile || error "touch $tfile failed"
20340         check_som_nologged
20341
20342         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
20343                 error "write $tfile failed"
20344         check_som_nologged
20345
20346         $TRUNCATE $DIR/$tfile 1234
20347         check_som_nologged
20348
20349         $TRUNCATE $DIR/$tfile 1048576
20350         check_som_nologged
20351
20352         # Deregistration step
20353         changelog_deregister || error "changelog_deregister failed"
20354 }
20355 run_test 808 "Check trusted.som xattr not logged in Changelogs"
20356
20357 check_som_nodata()
20358 {
20359         $LFS getsom $1
20360         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
20361 }
20362
20363 test_809() {
20364         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20365                 skip "Need MDS version at least 2.11.56"
20366
20367         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
20368                 error "failed to create DoM-only file $DIR/$tfile"
20369         touch $DIR/$tfile || error "touch $tfile failed"
20370         check_som_nodata $DIR/$tfile
20371
20372         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
20373                 error "write $tfile failed"
20374         check_som_nodata $DIR/$tfile
20375
20376         $TRUNCATE $DIR/$tfile 1234
20377         check_som_nodata $DIR/$tfile
20378
20379         $TRUNCATE $DIR/$tfile 4097
20380         check_som_nodata $DIR/$file
20381 }
20382 run_test 809 "Verify no SOM xattr store for DoM-only files"
20383
20384 test_810() {
20385         local ORIG
20386         local CSUM
20387
20388         # t10 seem to dislike partial pages
20389         lctl set_param osc.*.checksum_type=adler
20390         lctl set_param fail_loc=0x411
20391         dd if=/dev/urandom of=$DIR/$tfile bs=10240 count=2
20392         ORIG=$(md5sum $DIR/$tfile)
20393         lctl set_param ldlm.namespaces.*osc*.lru_size=clear
20394         CSUM=$(md5sum $DIR/$tfile)
20395         set_checksum_type adler
20396         if [ "$ORIG" != "$CSUM" ]; then
20397                 error "$ORIG != $CSUM"
20398         fi
20399 }
20400 run_test 810 "partial page writes on ZFS (LU-11663)"
20401
20402 test_811() {
20403         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
20404                 skip "Need MDS version at least 2.11.56"
20405
20406         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
20407         do_facet mds1 $LCTL set_param fail_loc=0x165
20408         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
20409
20410         stop mds1
20411         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20412
20413         sleep 5
20414         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
20415                 error "MDD orphan cleanup thread not quit"
20416 }
20417 run_test 811 "orphan name stub can be cleaned up in startup"
20418
20419 test_812() {
20420         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
20421                 skip "OST < 2.12.51 doesn't support this fail_loc"
20422
20423         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20424         # ensure ost1 is connected
20425         stat $DIR/$tfile >/dev/null || error "can't stat"
20426         wait_osc_import_state client ost1 FULL
20427         # no locks, no reqs to let the connection idle
20428         cancel_lru_locks osc
20429
20430         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
20431 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
20432         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
20433         wait_osc_import_state client ost1 CONNECTING
20434         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
20435
20436         stat $DIR/$tfile >/dev/null || error "can't stat file"
20437 }
20438 run_test 812 "do not drop reqs generated when imp is going to idle (LU-11951)"
20439
20440 test_813() {
20441         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
20442         [ -z "$file_heat_sav" ] && skip "no file heat support"
20443
20444         local readsample
20445         local writesample
20446         local readbyte
20447         local writebyte
20448         local readsample1
20449         local writesample1
20450         local readbyte1
20451         local writebyte1
20452
20453         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
20454         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
20455
20456         $LCTL set_param -n llite.*.file_heat=1
20457         echo "Turn on file heat"
20458         echo "Period second: $period_second, Decay percentage: $decay_pct"
20459
20460         echo "QQQQ" > $DIR/$tfile
20461         echo "QQQQ" > $DIR/$tfile
20462         echo "QQQQ" > $DIR/$tfile
20463         cat $DIR/$tfile > /dev/null
20464         cat $DIR/$tfile > /dev/null
20465         cat $DIR/$tfile > /dev/null
20466         cat $DIR/$tfile > /dev/null
20467
20468         local out=$($LFS heat_get $DIR/$tfile)
20469
20470         $LFS heat_get $DIR/$tfile
20471         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20472         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20473         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20474         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20475
20476         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
20477         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
20478         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
20479         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
20480
20481         sleep $((period_second + 3))
20482         echo "Sleep $((period_second + 3)) seconds..."
20483         # The recursion formula to calculate the heat of the file f is as
20484         # follow:
20485         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
20486         # Where Hi is the heat value in the period between time points i*I and
20487         # (i+1)*I; Ci is the access count in the period; the symbol P refers
20488         # to the weight of Ci.
20489         out=$($LFS heat_get $DIR/$tfile)
20490         $LFS heat_get $DIR/$tfile
20491         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20492         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20493         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20494         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20495
20496         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
20497                 error "read sample ($readsample) is wrong"
20498         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
20499                 error "write sample ($writesample) is wrong"
20500         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
20501                 error "read bytes ($readbyte) is wrong"
20502         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
20503                 error "write bytes ($writebyte) is wrong"
20504
20505         echo "QQQQ" > $DIR/$tfile
20506         echo "QQQQ" > $DIR/$tfile
20507         echo "QQQQ" > $DIR/$tfile
20508         cat $DIR/$tfile > /dev/null
20509         cat $DIR/$tfile > /dev/null
20510         cat $DIR/$tfile > /dev/null
20511         cat $DIR/$tfile > /dev/null
20512
20513         sleep $((period_second + 3))
20514         echo "Sleep $((period_second + 3)) seconds..."
20515
20516         out=$($LFS heat_get $DIR/$tfile)
20517         $LFS heat_get $DIR/$tfile
20518         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20519         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20520         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20521         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20522
20523         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
20524                 4 * $decay_pct) / 100") -eq 1 ] ||
20525                 error "read sample ($readsample1) is wrong"
20526         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
20527                 3 * $decay_pct) / 100") -eq 1 ] ||
20528                 error "write sample ($writesample1) is wrong"
20529         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
20530                 20 * $decay_pct) / 100") -eq 1 ] ||
20531                 error "read bytes ($readbyte1) is wrong"
20532         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
20533                 15 * $decay_pct) / 100") -eq 1 ] ||
20534                 error "write bytes ($writebyte1) is wrong"
20535
20536         echo "Turn off file heat for the file $DIR/$tfile"
20537         $LFS heat_set -o $DIR/$tfile
20538
20539         echo "QQQQ" > $DIR/$tfile
20540         echo "QQQQ" > $DIR/$tfile
20541         echo "QQQQ" > $DIR/$tfile
20542         cat $DIR/$tfile > /dev/null
20543         cat $DIR/$tfile > /dev/null
20544         cat $DIR/$tfile > /dev/null
20545         cat $DIR/$tfile > /dev/null
20546
20547         out=$($LFS heat_get $DIR/$tfile)
20548         $LFS heat_get $DIR/$tfile
20549         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20550         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20551         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20552         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20553
20554         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
20555         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
20556         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
20557         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
20558
20559         echo "Trun on file heat for the file $DIR/$tfile"
20560         $LFS heat_set -O $DIR/$tfile
20561
20562         echo "QQQQ" > $DIR/$tfile
20563         echo "QQQQ" > $DIR/$tfile
20564         echo "QQQQ" > $DIR/$tfile
20565         cat $DIR/$tfile > /dev/null
20566         cat $DIR/$tfile > /dev/null
20567         cat $DIR/$tfile > /dev/null
20568         cat $DIR/$tfile > /dev/null
20569
20570         out=$($LFS heat_get $DIR/$tfile)
20571         $LFS heat_get $DIR/$tfile
20572         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20573         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20574         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20575         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20576
20577         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
20578         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
20579         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
20580         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
20581
20582         $LFS heat_set -c $DIR/$tfile
20583         $LCTL set_param -n llite.*.file_heat=0
20584         echo "Turn off file heat support for the Lustre filesystem"
20585
20586         echo "QQQQ" > $DIR/$tfile
20587         echo "QQQQ" > $DIR/$tfile
20588         echo "QQQQ" > $DIR/$tfile
20589         cat $DIR/$tfile > /dev/null
20590         cat $DIR/$tfile > /dev/null
20591         cat $DIR/$tfile > /dev/null
20592         cat $DIR/$tfile > /dev/null
20593
20594         out=$($LFS heat_get $DIR/$tfile)
20595         $LFS heat_get $DIR/$tfile
20596         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20597         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20598         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20599         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20600
20601         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
20602         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
20603         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
20604         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
20605
20606         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
20607         rm -f $DIR/$tfile
20608 }
20609 run_test 813 "File heat verfication"
20610
20611 #
20612 # tests that do cleanup/setup should be run at the end
20613 #
20614
20615 test_900() {
20616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20617         local ls
20618
20619         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
20620         $LCTL set_param fail_loc=0x903
20621
20622         cancel_lru_locks MGC
20623
20624         FAIL_ON_ERROR=true cleanup
20625         FAIL_ON_ERROR=true setup
20626 }
20627 run_test 900 "umount should not race with any mgc requeue thread"
20628
20629 complete $SECONDS
20630 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
20631 check_and_cleanup_lustre
20632 if [ "$I_MOUNTED" != "yes" ]; then
20633         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
20634 fi
20635 exit_status