Whamcloud - gitweb
LU-13846 llite: move iov iter forward by ourself
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054 LU-13314
45 ALWAYS_EXCEPT+=" 407     312     56ob"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-9795 LU-9795 LU-9795 LU-9795
49         ALWAYS_EXCEPT+=" 17n     60a     133g    300f"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11596
61         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
62         # bug number:    LU-11671 LU-11667
63         ALWAYS_EXCEPT+=" 45       317"
64 fi
65
66 # skip nfs tests on kernels >= 4.14.0 until they are fixed
67 if [ $LINUX_VERSION_CODE -ge $(version_code 4.14.0) ]; then
68         # bug number:   LU-12661
69         ALWAYS_EXCEPT+=" 817"
70 fi
71 # skip cgroup tests on RHEL8.1 kernels until they are fixed
72 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
73       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
74         # bug number:   LU-13063
75         ALWAYS_EXCEPT+=" 411"
76 fi
77
78 #                                  5          12     8   12  (min)"
79 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 135 136 300o"
80
81 if [ "$mds1_FSTYPE" = "zfs" ]; then
82         # bug number for skipped test:
83         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  "
84         #                                               13    (min)"
85         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
86 fi
87
88 # Get the SLES distro version
89 #
90 # Returns a version string that should only be used in comparing
91 # strings returned by version_code()
92 sles_version_code()
93 {
94         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
95
96         # All SuSE Linux versions have one decimal. version_code expects two
97         local sles_version=$version.0
98         version_code $sles_version
99 }
100
101 # Check if we are running on Ubuntu or SLES so we can make decisions on
102 # what tests to run
103 if [ -r /etc/SuSE-release ]; then
104         sles_version=$(sles_version_code)
105         [ $sles_version -lt $(version_code 11.4.0) ] &&
106                 # bug number for skipped test: LU-4341
107                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
108         [ $sles_version -lt $(version_code 12.0.0) ] &&
109                 # bug number for skipped test: LU-3703
110                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
111 elif [ -r /etc/os-release ]; then
112         if grep -qi ubuntu /etc/os-release; then
113                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
114                                                 -e 's/^VERSION=//p' \
115                                                 /etc/os-release |
116                                                 awk '{ print $1 }'))
117
118                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
119                         # bug number for skipped test:
120                         #                LU-10334 LU-10366
121                         ALWAYS_EXCEPT+=" 103a     410"
122                 fi
123         fi
124 fi
125
126 build_test_filter
127 FAIL_ON_ERROR=false
128
129 cleanup() {
130         echo -n "cln.."
131         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
132         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
133 }
134 setup() {
135         echo -n "mnt.."
136         load_modules
137         setupall || exit 10
138         echo "done"
139 }
140
141 check_swap_layouts_support()
142 {
143         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
144                 skip "Does not support layout lock."
145 }
146
147 check_swap_layout_no_dom()
148 {
149         local FOLDER=$1
150         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
151         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
152 }
153
154 check_and_setup_lustre
155 DIR=${DIR:-$MOUNT}
156 assert_DIR
157
158 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
159
160 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
161 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
162 rm -rf $DIR/[Rdfs][0-9]*
163
164 # $RUNAS_ID may get set incorrectly somewhere else
165 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
166         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
167
168 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
169
170 if [ "${ONLY}" = "MOUNT" ] ; then
171         echo "Lustre is up, please go on"
172         exit
173 fi
174
175 echo "preparing for tests involving mounts"
176 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
177 touch $EXT2_DEV
178 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
179 echo # add a newline after mke2fs.
180
181 umask 077
182
183 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
184 lctl set_param debug=-1 2> /dev/null || true
185 test_0a() {
186         touch $DIR/$tfile
187         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
188         rm $DIR/$tfile
189         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
190 }
191 run_test 0a "touch; rm ====================="
192
193 test_0b() {
194         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
195         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
196 }
197 run_test 0b "chmod 0755 $DIR ============================="
198
199 test_0c() {
200         $LCTL get_param mdc.*.import | grep "state: FULL" ||
201                 error "import not FULL"
202         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
203                 error "bad target"
204 }
205 run_test 0c "check import proc"
206
207 test_0d() { # LU-3397
208         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
209                 skip "proc exports not supported before 2.10.57"
210
211         local mgs_exp="mgs.MGS.exports"
212         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
213         local exp_client_nid
214         local exp_client_version
215         local exp_val
216         local imp_val
217         local temp_imp=$DIR/$tfile.import
218         local temp_exp=$DIR/$tfile.export
219
220         # save mgc import file to $temp_imp
221         $LCTL get_param mgc.*.import | tee $temp_imp
222         # Check if client uuid is found in MGS export
223         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
224                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
225                         $client_uuid ] &&
226                         break;
227         done
228         # save mgs export file to $temp_exp
229         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
230
231         # Compare the value of field "connect_flags"
232         imp_val=$(grep "connect_flags" $temp_imp)
233         exp_val=$(grep "connect_flags" $temp_exp)
234         [ "$exp_val" == "$imp_val" ] ||
235                 error "export flags '$exp_val' != import flags '$imp_val'"
236
237         # Compare the value of client version
238         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
239         exp_val=$(version_code $exp_client_version)
240         imp_val=$CLIENT_VERSION
241         [ "$exp_val" == "$imp_val" ] ||
242                 error "export client version '$exp_val' != '$imp_val'"
243 }
244 run_test 0d "check export proc ============================="
245
246 test_1() {
247         test_mkdir $DIR/$tdir
248         test_mkdir $DIR/$tdir/d2
249         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
250         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
251         rmdir $DIR/$tdir/d2
252         rmdir $DIR/$tdir
253         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
254 }
255 run_test 1 "mkdir; remkdir; rmdir"
256
257 test_2() {
258         test_mkdir $DIR/$tdir
259         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
260         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
261         rm -r $DIR/$tdir
262         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
263 }
264 run_test 2 "mkdir; touch; rmdir; check file"
265
266 test_3() {
267         test_mkdir $DIR/$tdir
268         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
269         touch $DIR/$tdir/$tfile
270         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
271         rm -r $DIR/$tdir
272         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
273 }
274 run_test 3 "mkdir; touch; rmdir; check dir"
275
276 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
277 test_4() {
278         test_mkdir -i 1 $DIR/$tdir
279
280         touch $DIR/$tdir/$tfile ||
281                 error "Create file under remote directory failed"
282
283         rmdir $DIR/$tdir &&
284                 error "Expect error removing in-use dir $DIR/$tdir"
285
286         test -d $DIR/$tdir || error "Remote directory disappeared"
287
288         rm -rf $DIR/$tdir || error "remove remote dir error"
289 }
290 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
291
292 test_5() {
293         test_mkdir $DIR/$tdir
294         test_mkdir $DIR/$tdir/d2
295         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
296         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
297         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
298 }
299 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
300
301 test_6a() {
302         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
303         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
304         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
305                 error "$tfile does not have perm 0666 or UID $UID"
306         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
307         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
308                 error "$tfile should be 0666 and owned by UID $UID"
309 }
310 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
311
312 test_6c() {
313         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
314
315         touch $DIR/$tfile
316         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
317         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
318                 error "$tfile should be owned by UID $RUNAS_ID"
319         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
320         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
321                 error "$tfile should be owned by UID $RUNAS_ID"
322 }
323 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
324
325 test_6e() {
326         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
327
328         touch $DIR/$tfile
329         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
330         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
331                 error "$tfile should be owned by GID $UID"
332         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
333         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
334                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
335 }
336 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
337
338 test_6g() {
339         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
340
341         test_mkdir $DIR/$tdir
342         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
343         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
344         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
345         test_mkdir $DIR/$tdir/d/subdir
346         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
347                 error "$tdir/d/subdir should be GID $RUNAS_GID"
348         if [[ $MDSCOUNT -gt 1 ]]; then
349                 # check remote dir sgid inherite
350                 $LFS mkdir -i 0 $DIR/$tdir.local ||
351                         error "mkdir $tdir.local failed"
352                 chmod g+s $DIR/$tdir.local ||
353                         error "chmod $tdir.local failed"
354                 chgrp $RUNAS_GID $DIR/$tdir.local ||
355                         error "chgrp $tdir.local failed"
356                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
357                         error "mkdir $tdir.remote failed"
358                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
359                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
360                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
361                         error "$tdir.remote should be mode 02755"
362         fi
363 }
364 run_test 6g "verify new dir in sgid dir inherits group"
365
366 test_6h() { # bug 7331
367         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
368
369         touch $DIR/$tfile || error "touch failed"
370         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
371         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
372                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
373         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
374                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
375 }
376 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
377
378 test_7a() {
379         test_mkdir $DIR/$tdir
380         $MCREATE $DIR/$tdir/$tfile
381         chmod 0666 $DIR/$tdir/$tfile
382         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
383                 error "$tdir/$tfile should be mode 0666"
384 }
385 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
386
387 test_7b() {
388         if [ ! -d $DIR/$tdir ]; then
389                 test_mkdir $DIR/$tdir
390         fi
391         $MCREATE $DIR/$tdir/$tfile
392         echo -n foo > $DIR/$tdir/$tfile
393         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
394         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
395 }
396 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
397
398 test_8() {
399         test_mkdir $DIR/$tdir
400         touch $DIR/$tdir/$tfile
401         chmod 0666 $DIR/$tdir/$tfile
402         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
403                 error "$tfile mode not 0666"
404 }
405 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
406
407 test_9() {
408         test_mkdir $DIR/$tdir
409         test_mkdir $DIR/$tdir/d2
410         test_mkdir $DIR/$tdir/d2/d3
411         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
412 }
413 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
414
415 test_10() {
416         test_mkdir $DIR/$tdir
417         test_mkdir $DIR/$tdir/d2
418         touch $DIR/$tdir/d2/$tfile
419         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
420                 error "$tdir/d2/$tfile not a file"
421 }
422 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
423
424 test_11() {
425         test_mkdir $DIR/$tdir
426         test_mkdir $DIR/$tdir/d2
427         chmod 0666 $DIR/$tdir/d2
428         chmod 0705 $DIR/$tdir/d2
429         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
430                 error "$tdir/d2 mode not 0705"
431 }
432 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
433
434 test_12() {
435         test_mkdir $DIR/$tdir
436         touch $DIR/$tdir/$tfile
437         chmod 0666 $DIR/$tdir/$tfile
438         chmod 0654 $DIR/$tdir/$tfile
439         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
440                 error "$tdir/d2 mode not 0654"
441 }
442 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
443
444 test_13() {
445         test_mkdir $DIR/$tdir
446         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
447         >  $DIR/$tdir/$tfile
448         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
449                 error "$tdir/$tfile size not 0 after truncate"
450 }
451 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
452
453 test_14() {
454         test_mkdir $DIR/$tdir
455         touch $DIR/$tdir/$tfile
456         rm $DIR/$tdir/$tfile
457         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
458 }
459 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
460
461 test_15() {
462         test_mkdir $DIR/$tdir
463         touch $DIR/$tdir/$tfile
464         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
465         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
466                 error "$tdir/${tfile_2} not a file after rename"
467         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
468 }
469 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
470
471 test_16() {
472         test_mkdir $DIR/$tdir
473         touch $DIR/$tdir/$tfile
474         rm -rf $DIR/$tdir/$tfile
475         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
476 }
477 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
478
479 test_17a() {
480         test_mkdir $DIR/$tdir
481         touch $DIR/$tdir/$tfile
482         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
483         ls -l $DIR/$tdir
484         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
485                 error "$tdir/l-exist not a symlink"
486         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
487                 error "$tdir/l-exist not referencing a file"
488         rm -f $DIR/$tdir/l-exist
489         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
490 }
491 run_test 17a "symlinks: create, remove (real)"
492
493 test_17b() {
494         test_mkdir $DIR/$tdir
495         ln -s no-such-file $DIR/$tdir/l-dangle
496         ls -l $DIR/$tdir
497         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
498                 error "$tdir/l-dangle not referencing no-such-file"
499         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
500                 error "$tdir/l-dangle not referencing non-existent file"
501         rm -f $DIR/$tdir/l-dangle
502         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
503 }
504 run_test 17b "symlinks: create, remove (dangling)"
505
506 test_17c() { # bug 3440 - don't save failed open RPC for replay
507         test_mkdir $DIR/$tdir
508         ln -s foo $DIR/$tdir/$tfile
509         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
510 }
511 run_test 17c "symlinks: open dangling (should return error)"
512
513 test_17d() {
514         test_mkdir $DIR/$tdir
515         ln -s foo $DIR/$tdir/$tfile
516         touch $DIR/$tdir/$tfile || error "creating to new symlink"
517 }
518 run_test 17d "symlinks: create dangling"
519
520 test_17e() {
521         test_mkdir $DIR/$tdir
522         local foo=$DIR/$tdir/$tfile
523         ln -s $foo $foo || error "create symlink failed"
524         ls -l $foo || error "ls -l failed"
525         ls $foo && error "ls not failed" || true
526 }
527 run_test 17e "symlinks: create recursive symlink (should return error)"
528
529 test_17f() {
530         test_mkdir $DIR/$tdir
531         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
532         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
533         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
534         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
535         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
536         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
537         ls -l  $DIR/$tdir
538 }
539 run_test 17f "symlinks: long and very long symlink name"
540
541 # str_repeat(S, N) generate a string that is string S repeated N times
542 str_repeat() {
543         local s=$1
544         local n=$2
545         local ret=''
546         while [ $((n -= 1)) -ge 0 ]; do
547                 ret=$ret$s
548         done
549         echo $ret
550 }
551
552 # Long symlinks and LU-2241
553 test_17g() {
554         test_mkdir $DIR/$tdir
555         local TESTS="59 60 61 4094 4095"
556
557         # Fix for inode size boundary in 2.1.4
558         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
559                 TESTS="4094 4095"
560
561         # Patch not applied to 2.2 or 2.3 branches
562         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
563         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
564                 TESTS="4094 4095"
565
566         for i in $TESTS; do
567                 local SYMNAME=$(str_repeat 'x' $i)
568                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
569                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
570         done
571 }
572 run_test 17g "symlinks: really long symlink name and inode boundaries"
573
574 test_17h() { #bug 17378
575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
576         remote_mds_nodsh && skip "remote MDS with nodsh"
577
578         local mdt_idx
579
580         test_mkdir $DIR/$tdir
581         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
582         $LFS setstripe -c -1 $DIR/$tdir
583         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
584         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
585         touch $DIR/$tdir/$tfile || true
586 }
587 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
588
589 test_17i() { #bug 20018
590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
591         remote_mds_nodsh && skip "remote MDS with nodsh"
592
593         local foo=$DIR/$tdir/$tfile
594         local mdt_idx
595
596         test_mkdir -c1 $DIR/$tdir
597         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
598         ln -s $foo $foo || error "create symlink failed"
599 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
600         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
601         ls -l $foo && error "error not detected"
602         return 0
603 }
604 run_test 17i "don't panic on short symlink (should return error)"
605
606 test_17k() { #bug 22301
607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
608         [[ -z "$(which rsync 2>/dev/null)" ]] &&
609                 skip "no rsync command"
610         rsync --help | grep -q xattr ||
611                 skip_env "$(rsync --version | head -n1) does not support xattrs"
612         test_mkdir $DIR/$tdir
613         test_mkdir $DIR/$tdir.new
614         touch $DIR/$tdir/$tfile
615         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
616         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
617                 error "rsync failed with xattrs enabled"
618 }
619 run_test 17k "symlinks: rsync with xattrs enabled"
620
621 test_17l() { # LU-279
622         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
623                 skip "no getfattr command"
624
625         test_mkdir $DIR/$tdir
626         touch $DIR/$tdir/$tfile
627         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
628         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
629                 # -h to not follow symlinks. -m '' to list all the xattrs.
630                 # grep to remove first line: '# file: $path'.
631                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
632                 do
633                         lgetxattr_size_check $path $xattr ||
634                                 error "lgetxattr_size_check $path $xattr failed"
635                 done
636         done
637 }
638 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
639
640 # LU-1540
641 test_17m() {
642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
643         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
644         remote_mds_nodsh && skip "remote MDS with nodsh"
645         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
646         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
647                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
648
649         local short_sym="0123456789"
650         local wdir=$DIR/$tdir
651         local i
652
653         test_mkdir $wdir
654         long_sym=$short_sym
655         # create a long symlink file
656         for ((i = 0; i < 4; ++i)); do
657                 long_sym=${long_sym}${long_sym}
658         done
659
660         echo "create 512 short and long symlink files under $wdir"
661         for ((i = 0; i < 256; ++i)); do
662                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
663                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
664         done
665
666         echo "erase them"
667         rm -f $wdir/*
668         sync
669         wait_delete_completed
670
671         echo "recreate the 512 symlink files with a shorter string"
672         for ((i = 0; i < 512; ++i)); do
673                 # rewrite the symlink file with a shorter string
674                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
675                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
676         done
677
678         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
679         local devname=$(mdsdevname $mds_index)
680
681         echo "stop and checking mds${mds_index}:"
682         # e2fsck should not return error
683         stop mds${mds_index}
684         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
685         rc=$?
686
687         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
688                 error "start mds${mds_index} failed"
689         df $MOUNT > /dev/null 2>&1
690         [ $rc -eq 0 ] ||
691                 error "e2fsck detected error for short/long symlink: rc=$rc"
692         rm -f $wdir/*
693 }
694 run_test 17m "run e2fsck against MDT which contains short/long symlink"
695
696 check_fs_consistency_17n() {
697         local mdt_index
698         local rc=0
699
700         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
701         # so it only check MDT1/MDT2 instead of all of MDTs.
702         for mdt_index in 1 2; do
703                 local devname=$(mdsdevname $mdt_index)
704                 # e2fsck should not return error
705                 stop mds${mdt_index}
706                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
707                         rc=$((rc + $?))
708
709                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
710                         error "mount mds$mdt_index failed"
711                 df $MOUNT > /dev/null 2>&1
712         done
713         return $rc
714 }
715
716 test_17n() {
717         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
719         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
720         remote_mds_nodsh && skip "remote MDS with nodsh"
721         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
722         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
723                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
724
725         local i
726
727         test_mkdir $DIR/$tdir
728         for ((i=0; i<10; i++)); do
729                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
730                         error "create remote dir error $i"
731                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
732                         error "create files under remote dir failed $i"
733         done
734
735         check_fs_consistency_17n ||
736                 error "e2fsck report error after create files under remote dir"
737
738         for ((i = 0; i < 10; i++)); do
739                 rm -rf $DIR/$tdir/remote_dir_${i} ||
740                         error "destroy remote dir error $i"
741         done
742
743         check_fs_consistency_17n ||
744                 error "e2fsck report error after unlink files under remote dir"
745
746         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
747                 skip "lustre < 2.4.50 does not support migrate mv"
748
749         for ((i = 0; i < 10; i++)); do
750                 mkdir -p $DIR/$tdir/remote_dir_${i}
751                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
752                         error "create files under remote dir failed $i"
753                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
754                         error "migrate remote dir error $i"
755         done
756         check_fs_consistency_17n || error "e2fsck report error after migration"
757
758         for ((i = 0; i < 10; i++)); do
759                 rm -rf $DIR/$tdir/remote_dir_${i} ||
760                         error "destroy remote dir error $i"
761         done
762
763         check_fs_consistency_17n || error "e2fsck report error after unlink"
764 }
765 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
766
767 test_17o() {
768         remote_mds_nodsh && skip "remote MDS with nodsh"
769         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
770                 skip "Need MDS version at least 2.3.64"
771
772         local wdir=$DIR/${tdir}o
773         local mdt_index
774         local rc=0
775
776         test_mkdir $wdir
777         touch $wdir/$tfile
778         mdt_index=$($LFS getstripe -m $wdir/$tfile)
779         mdt_index=$((mdt_index + 1))
780
781         cancel_lru_locks mdc
782         #fail mds will wait the failover finish then set
783         #following fail_loc to avoid interfer the recovery process.
784         fail mds${mdt_index}
785
786         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
787         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
788         ls -l $wdir/$tfile && rc=1
789         do_facet mds${mdt_index} lctl set_param fail_loc=0
790         [[ $rc -eq 0 ]] || error "stat file should fail"
791 }
792 run_test 17o "stat file with incompat LMA feature"
793
794 test_18() {
795         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
796         ls $DIR || error "Failed to ls $DIR: $?"
797 }
798 run_test 18 "touch .../f ; ls ... =============================="
799
800 test_19a() {
801         touch $DIR/$tfile
802         ls -l $DIR
803         rm $DIR/$tfile
804         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
805 }
806 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
807
808 test_19b() {
809         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
810 }
811 run_test 19b "ls -l .../f19 (should return error) =============="
812
813 test_19c() {
814         [ $RUNAS_ID -eq $UID ] &&
815                 skip_env "RUNAS_ID = UID = $UID -- skipping"
816
817         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
818 }
819 run_test 19c "$RUNAS touch .../f19 (should return error) =="
820
821 test_19d() {
822         cat $DIR/f19 && error || true
823 }
824 run_test 19d "cat .../f19 (should return error) =============="
825
826 test_20() {
827         touch $DIR/$tfile
828         rm $DIR/$tfile
829         touch $DIR/$tfile
830         rm $DIR/$tfile
831         touch $DIR/$tfile
832         rm $DIR/$tfile
833         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
834 }
835 run_test 20 "touch .../f ; ls -l ..."
836
837 test_21() {
838         test_mkdir $DIR/$tdir
839         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
840         ln -s dangle $DIR/$tdir/link
841         echo foo >> $DIR/$tdir/link
842         cat $DIR/$tdir/dangle
843         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
844         $CHECKSTAT -f -t file $DIR/$tdir/link ||
845                 error "$tdir/link not linked to a file"
846 }
847 run_test 21 "write to dangling link"
848
849 test_22() {
850         local wdir=$DIR/$tdir
851         test_mkdir $wdir
852         chown $RUNAS_ID:$RUNAS_GID $wdir
853         (cd $wdir || error "cd $wdir failed";
854                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
855                 $RUNAS tar xf -)
856         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
857         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
858         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
859                 error "checkstat -u failed"
860 }
861 run_test 22 "unpack tar archive as non-root user"
862
863 # was test_23
864 test_23a() {
865         test_mkdir $DIR/$tdir
866         local file=$DIR/$tdir/$tfile
867
868         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
869         openfile -f O_CREAT:O_EXCL $file &&
870                 error "$file recreate succeeded" || true
871 }
872 run_test 23a "O_CREAT|O_EXCL in subdir"
873
874 test_23b() { # bug 18988
875         test_mkdir $DIR/$tdir
876         local file=$DIR/$tdir/$tfile
877
878         rm -f $file
879         echo foo > $file || error "write filed"
880         echo bar >> $file || error "append filed"
881         $CHECKSTAT -s 8 $file || error "wrong size"
882         rm $file
883 }
884 run_test 23b "O_APPEND check"
885
886 # LU-9409, size with O_APPEND and tiny writes
887 test_23c() {
888         local file=$DIR/$tfile
889
890         # single dd
891         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
892         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
893         rm -f $file
894
895         # racing tiny writes
896         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
897         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
898         wait
899         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
900         rm -f $file
901
902         #racing tiny & normal writes
903         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
904         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
905         wait
906         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
907         rm -f $file
908
909         #racing tiny & normal writes 2, ugly numbers
910         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
911         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
912         wait
913         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
914         rm -f $file
915 }
916 run_test 23c "O_APPEND size checks for tiny writes"
917
918 # LU-11069 file offset is correct after appending writes
919 test_23d() {
920         local file=$DIR/$tfile
921         local offset
922
923         echo CentaurHauls > $file
924         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
925         if ((offset != 26)); then
926                 error "wrong offset, expected 26, got '$offset'"
927         fi
928 }
929 run_test 23d "file offset is correct after appending writes"
930
931 # rename sanity
932 test_24a() {
933         echo '-- same directory rename'
934         test_mkdir $DIR/$tdir
935         touch $DIR/$tdir/$tfile.1
936         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
937         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
938 }
939 run_test 24a "rename file to non-existent target"
940
941 test_24b() {
942         test_mkdir $DIR/$tdir
943         touch $DIR/$tdir/$tfile.{1,2}
944         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
945         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
946         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
947 }
948 run_test 24b "rename file to existing target"
949
950 test_24c() {
951         test_mkdir $DIR/$tdir
952         test_mkdir $DIR/$tdir/d$testnum.1
953         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
954         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
955         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
956 }
957 run_test 24c "rename directory to non-existent target"
958
959 test_24d() {
960         test_mkdir -c1 $DIR/$tdir
961         test_mkdir -c1 $DIR/$tdir/d$testnum.1
962         test_mkdir -c1 $DIR/$tdir/d$testnum.2
963         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
964         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
965         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
966 }
967 run_test 24d "rename directory to existing target"
968
969 test_24e() {
970         echo '-- cross directory renames --'
971         test_mkdir $DIR/R5a
972         test_mkdir $DIR/R5b
973         touch $DIR/R5a/f
974         mv $DIR/R5a/f $DIR/R5b/g
975         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
976         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
977 }
978 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
979
980 test_24f() {
981         test_mkdir $DIR/R6a
982         test_mkdir $DIR/R6b
983         touch $DIR/R6a/f $DIR/R6b/g
984         mv $DIR/R6a/f $DIR/R6b/g
985         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
986         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
987 }
988 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
989
990 test_24g() {
991         test_mkdir $DIR/R7a
992         test_mkdir $DIR/R7b
993         test_mkdir $DIR/R7a/d
994         mv $DIR/R7a/d $DIR/R7b/e
995         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
996         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
997 }
998 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
999
1000 test_24h() {
1001         test_mkdir -c1 $DIR/R8a
1002         test_mkdir -c1 $DIR/R8b
1003         test_mkdir -c1 $DIR/R8a/d
1004         test_mkdir -c1 $DIR/R8b/e
1005         mrename $DIR/R8a/d $DIR/R8b/e
1006         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1007         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1008 }
1009 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1010
1011 test_24i() {
1012         echo "-- rename error cases"
1013         test_mkdir $DIR/R9
1014         test_mkdir $DIR/R9/a
1015         touch $DIR/R9/f
1016         mrename $DIR/R9/f $DIR/R9/a
1017         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1018         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1019         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1020 }
1021 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1022
1023 test_24j() {
1024         test_mkdir $DIR/R10
1025         mrename $DIR/R10/f $DIR/R10/g
1026         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1027         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1028         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1029 }
1030 run_test 24j "source does not exist ============================"
1031
1032 test_24k() {
1033         test_mkdir $DIR/R11a
1034         test_mkdir $DIR/R11a/d
1035         touch $DIR/R11a/f
1036         mv $DIR/R11a/f $DIR/R11a/d
1037         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1038         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1039 }
1040 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1041
1042 # bug 2429 - rename foo foo foo creates invalid file
1043 test_24l() {
1044         f="$DIR/f24l"
1045         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1046 }
1047 run_test 24l "Renaming a file to itself ========================"
1048
1049 test_24m() {
1050         f="$DIR/f24m"
1051         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1052         # on ext3 this does not remove either the source or target files
1053         # though the "expected" operation would be to remove the source
1054         $CHECKSTAT -t file ${f} || error "${f} missing"
1055         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1056 }
1057 run_test 24m "Renaming a file to a hard link to itself ========="
1058
1059 test_24n() {
1060     f="$DIR/f24n"
1061     # this stats the old file after it was renamed, so it should fail
1062     touch ${f}
1063     $CHECKSTAT ${f} || error "${f} missing"
1064     mv ${f} ${f}.rename
1065     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1066     $CHECKSTAT -a ${f} || error "${f} exists"
1067 }
1068 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1069
1070 test_24o() {
1071         test_mkdir $DIR/$tdir
1072         rename_many -s random -v -n 10 $DIR/$tdir
1073 }
1074 run_test 24o "rename of files during htree split"
1075
1076 test_24p() {
1077         test_mkdir $DIR/R12a
1078         test_mkdir $DIR/R12b
1079         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1080         mrename $DIR/R12a $DIR/R12b
1081         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1082         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1083         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1084         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1085 }
1086 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1087
1088 cleanup_multiop_pause() {
1089         trap 0
1090         kill -USR1 $MULTIPID
1091 }
1092
1093 test_24q() {
1094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1095
1096         test_mkdir $DIR/R13a
1097         test_mkdir $DIR/R13b
1098         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1099         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1100         MULTIPID=$!
1101
1102         trap cleanup_multiop_pause EXIT
1103         mrename $DIR/R13a $DIR/R13b
1104         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1105         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1106         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1107         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1108         cleanup_multiop_pause
1109         wait $MULTIPID || error "multiop close failed"
1110 }
1111 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1112
1113 test_24r() { #bug 3789
1114         test_mkdir $DIR/R14a
1115         test_mkdir $DIR/R14a/b
1116         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1117         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1118         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1119 }
1120 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1121
1122 test_24s() {
1123         test_mkdir $DIR/R15a
1124         test_mkdir $DIR/R15a/b
1125         test_mkdir $DIR/R15a/b/c
1126         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1127         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1128         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1129 }
1130 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1131 test_24t() {
1132         test_mkdir $DIR/R16a
1133         test_mkdir $DIR/R16a/b
1134         test_mkdir $DIR/R16a/b/c
1135         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1136         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1137         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1138 }
1139 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1140
1141 test_24u() { # bug12192
1142         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1143         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1144 }
1145 run_test 24u "create stripe file"
1146
1147 simple_cleanup_common() {
1148         local rc=0
1149         trap 0
1150         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1151
1152         local start=$SECONDS
1153         rm -rf $DIR/$tdir
1154         rc=$?
1155         wait_delete_completed
1156         echo "cleanup time $((SECONDS - start))"
1157         return $rc
1158 }
1159
1160 max_pages_per_rpc() {
1161         local mdtname="$(printf "MDT%04x" ${1:-0})"
1162         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1163 }
1164
1165 test_24v() {
1166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1167
1168         local nrfiles=${COUNT:-100000}
1169         local fname="$DIR/$tdir/$tfile"
1170
1171         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1172         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1173
1174         test_mkdir "$(dirname $fname)"
1175         # assume MDT0000 has the fewest inodes
1176         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1177         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1178         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1179
1180         trap simple_cleanup_common EXIT
1181
1182         createmany -m "$fname" $nrfiles
1183
1184         cancel_lru_locks mdc
1185         lctl set_param mdc.*.stats clear
1186
1187         # was previously test_24D: LU-6101
1188         # readdir() returns correct number of entries after cursor reload
1189         local num_ls=$(ls $DIR/$tdir | wc -l)
1190         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1191         local num_all=$(ls -a $DIR/$tdir | wc -l)
1192         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1193                 [ $num_all -ne $((nrfiles + 2)) ]; then
1194                         error "Expected $nrfiles files, got $num_ls " \
1195                                 "($num_uniq unique $num_all .&..)"
1196         fi
1197         # LU-5 large readdir
1198         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1199         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1200         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1201         # take into account of overhead in lu_dirpage header and end mark in
1202         # each page, plus one in rpc_num calculation.
1203         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1204         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1205         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1206         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1207         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1208         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1209         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1210         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1211                 error "large readdir doesn't take effect: " \
1212                       "$mds_readpage should be about $rpc_max"
1213
1214         simple_cleanup_common
1215 }
1216 run_test 24v "list large directory (test hash collision, b=17560)"
1217
1218 test_24w() { # bug21506
1219         SZ1=234852
1220         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1221         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1222         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1223         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1224         [[ "$SZ1" -eq "$SZ2" ]] ||
1225                 error "Error reading at the end of the file $tfile"
1226 }
1227 run_test 24w "Reading a file larger than 4Gb"
1228
1229 test_24x() {
1230         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1232         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1233                 skip "Need MDS version at least 2.7.56"
1234
1235         local MDTIDX=1
1236         local remote_dir=$DIR/$tdir/remote_dir
1237
1238         test_mkdir $DIR/$tdir
1239         $LFS mkdir -i $MDTIDX $remote_dir ||
1240                 error "create remote directory failed"
1241
1242         test_mkdir $DIR/$tdir/src_dir
1243         touch $DIR/$tdir/src_file
1244         test_mkdir $remote_dir/tgt_dir
1245         touch $remote_dir/tgt_file
1246
1247         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1248                 error "rename dir cross MDT failed!"
1249
1250         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1251                 error "rename file cross MDT failed!"
1252
1253         touch $DIR/$tdir/ln_file
1254         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1255                 error "ln file cross MDT failed"
1256
1257         rm -rf $DIR/$tdir || error "Can not delete directories"
1258 }
1259 run_test 24x "cross MDT rename/link"
1260
1261 test_24y() {
1262         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1264
1265         local remote_dir=$DIR/$tdir/remote_dir
1266         local mdtidx=1
1267
1268         test_mkdir $DIR/$tdir
1269         $LFS mkdir -i $mdtidx $remote_dir ||
1270                 error "create remote directory failed"
1271
1272         test_mkdir $remote_dir/src_dir
1273         touch $remote_dir/src_file
1274         test_mkdir $remote_dir/tgt_dir
1275         touch $remote_dir/tgt_file
1276
1277         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1278                 error "rename subdir in the same remote dir failed!"
1279
1280         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1281                 error "rename files in the same remote dir failed!"
1282
1283         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1284                 error "link files in the same remote dir failed!"
1285
1286         rm -rf $DIR/$tdir || error "Can not delete directories"
1287 }
1288 run_test 24y "rename/link on the same dir should succeed"
1289
1290 test_24z() {
1291         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1292         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1293                 skip "Need MDS version at least 2.12.51"
1294
1295         local index
1296
1297         for index in 0 1; do
1298                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1299                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1300         done
1301
1302         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1303
1304         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1305         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1306
1307         local mdts=$(comma_list $(mdts_nodes))
1308
1309         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1310         stack_trap "do_nodes $mdts $LCTL \
1311                 set_param mdt.*.enable_remote_rename=1" EXIT
1312
1313         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1314
1315         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1316         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1317 }
1318 run_test 24z "cross-MDT rename is done as cp"
1319
1320 test_24A() { # LU-3182
1321         local NFILES=5000
1322
1323         rm -rf $DIR/$tdir
1324         test_mkdir $DIR/$tdir
1325         trap simple_cleanup_common EXIT
1326         createmany -m $DIR/$tdir/$tfile $NFILES
1327         local t=$(ls $DIR/$tdir | wc -l)
1328         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1329         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1330         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1331            [ $v -ne $((NFILES + 2)) ] ; then
1332                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1333         fi
1334
1335         simple_cleanup_common || error "Can not delete directories"
1336 }
1337 run_test 24A "readdir() returns correct number of entries."
1338
1339 test_24B() { # LU-4805
1340         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1341
1342         local count
1343
1344         test_mkdir $DIR/$tdir
1345         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1346                 error "create striped dir failed"
1347
1348         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1349         [ $count -eq 2 ] || error "Expected 2, got $count"
1350
1351         touch $DIR/$tdir/striped_dir/a
1352
1353         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1354         [ $count -eq 3 ] || error "Expected 3, got $count"
1355
1356         touch $DIR/$tdir/striped_dir/.f
1357
1358         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1359         [ $count -eq 4 ] || error "Expected 4, got $count"
1360
1361         rm -rf $DIR/$tdir || error "Can not delete directories"
1362 }
1363 run_test 24B "readdir for striped dir return correct number of entries"
1364
1365 test_24C() {
1366         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1367
1368         mkdir $DIR/$tdir
1369         mkdir $DIR/$tdir/d0
1370         mkdir $DIR/$tdir/d1
1371
1372         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1373                 error "create striped dir failed"
1374
1375         cd $DIR/$tdir/d0/striped_dir
1376
1377         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1378         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1379         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1380
1381         [ "$d0_ino" = "$parent_ino" ] ||
1382                 error ".. wrong, expect $d0_ino, get $parent_ino"
1383
1384         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1385                 error "mv striped dir failed"
1386
1387         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1388
1389         [ "$d1_ino" = "$parent_ino" ] ||
1390                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1391 }
1392 run_test 24C "check .. in striped dir"
1393
1394 test_24E() {
1395         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1397
1398         mkdir -p $DIR/$tdir
1399         mkdir $DIR/$tdir/src_dir
1400         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1401                 error "create remote source failed"
1402
1403         touch $DIR/$tdir/src_dir/src_child/a
1404
1405         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1406                 error "create remote target dir failed"
1407
1408         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1409                 error "create remote target child failed"
1410
1411         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1412                 error "rename dir cross MDT failed!"
1413
1414         find $DIR/$tdir
1415
1416         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1417                 error "src_child still exists after rename"
1418
1419         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1420                 error "missing file(a) after rename"
1421
1422         rm -rf $DIR/$tdir || error "Can not delete directories"
1423 }
1424 run_test 24E "cross MDT rename/link"
1425
1426 test_24F () {
1427         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1428
1429         local repeats=1000
1430         [ "$SLOW" = "no" ] && repeats=100
1431
1432         mkdir -p $DIR/$tdir
1433
1434         echo "$repeats repeats"
1435         for ((i = 0; i < repeats; i++)); do
1436                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1437                 touch $DIR/$tdir/test/a || error "touch fails"
1438                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1439                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1440         done
1441
1442         true
1443 }
1444 run_test 24F "hash order vs readdir (LU-11330)"
1445
1446 test_25a() {
1447         echo '== symlink sanity ============================================='
1448
1449         test_mkdir $DIR/d25
1450         ln -s d25 $DIR/s25
1451         touch $DIR/s25/foo ||
1452                 error "File creation in symlinked directory failed"
1453 }
1454 run_test 25a "create file in symlinked directory ==============="
1455
1456 test_25b() {
1457         [ ! -d $DIR/d25 ] && test_25a
1458         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1459 }
1460 run_test 25b "lookup file in symlinked directory ==============="
1461
1462 test_26a() {
1463         test_mkdir $DIR/d26
1464         test_mkdir $DIR/d26/d26-2
1465         ln -s d26/d26-2 $DIR/s26
1466         touch $DIR/s26/foo || error "File creation failed"
1467 }
1468 run_test 26a "multiple component symlink ======================="
1469
1470 test_26b() {
1471         test_mkdir -p $DIR/$tdir/d26-2
1472         ln -s $tdir/d26-2/foo $DIR/s26-2
1473         touch $DIR/s26-2 || error "File creation failed"
1474 }
1475 run_test 26b "multiple component symlink at end of lookup ======"
1476
1477 test_26c() {
1478         test_mkdir $DIR/d26.2
1479         touch $DIR/d26.2/foo
1480         ln -s d26.2 $DIR/s26.2-1
1481         ln -s s26.2-1 $DIR/s26.2-2
1482         ln -s s26.2-2 $DIR/s26.2-3
1483         chmod 0666 $DIR/s26.2-3/foo
1484 }
1485 run_test 26c "chain of symlinks"
1486
1487 # recursive symlinks (bug 439)
1488 test_26d() {
1489         ln -s d26-3/foo $DIR/d26-3
1490 }
1491 run_test 26d "create multiple component recursive symlink"
1492
1493 test_26e() {
1494         [ ! -h $DIR/d26-3 ] && test_26d
1495         rm $DIR/d26-3
1496 }
1497 run_test 26e "unlink multiple component recursive symlink"
1498
1499 # recursive symlinks (bug 7022)
1500 test_26f() {
1501         test_mkdir $DIR/$tdir
1502         test_mkdir $DIR/$tdir/$tfile
1503         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1504         test_mkdir -p lndir/bar1
1505         test_mkdir $DIR/$tdir/$tfile/$tfile
1506         cd $tfile                || error "cd $tfile failed"
1507         ln -s .. dotdot          || error "ln dotdot failed"
1508         ln -s dotdot/lndir lndir || error "ln lndir failed"
1509         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1510         output=`ls $tfile/$tfile/lndir/bar1`
1511         [ "$output" = bar1 ] && error "unexpected output"
1512         rm -r $tfile             || error "rm $tfile failed"
1513         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1514 }
1515 run_test 26f "rm -r of a directory which has recursive symlink"
1516
1517 test_27a() {
1518         test_mkdir $DIR/$tdir
1519         $LFS getstripe $DIR/$tdir
1520         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1521         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1522         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1523 }
1524 run_test 27a "one stripe file"
1525
1526 test_27b() {
1527         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1528
1529         test_mkdir $DIR/$tdir
1530         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1531         $LFS getstripe -c $DIR/$tdir/$tfile
1532         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1533                 error "two-stripe file doesn't have two stripes"
1534
1535         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1536 }
1537 run_test 27b "create and write to two stripe file"
1538
1539 # 27c family tests specific striping, setstripe -o
1540 test_27ca() {
1541         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1542         test_mkdir -p $DIR/$tdir
1543         local osts="1"
1544
1545         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1546         $LFS getstripe -i $DIR/$tdir/$tfile
1547         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1548                 error "stripe not on specified OST"
1549
1550         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1551 }
1552 run_test 27ca "one stripe on specified OST"
1553
1554 test_27cb() {
1555         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1556         test_mkdir -p $DIR/$tdir
1557         local osts="1,0"
1558         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1559         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1560         echo "$getstripe"
1561
1562         # Strip getstripe output to a space separated list of OSTs
1563         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1564                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1565         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1566                 error "stripes not on specified OSTs"
1567
1568         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1569 }
1570 run_test 27cb "two stripes on specified OSTs"
1571
1572 test_27cc() {
1573         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1574         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1575                 skip "server does not support overstriping"
1576
1577         test_mkdir -p $DIR/$tdir
1578         local osts="0,0"
1579         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1580         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1581         echo "$getstripe"
1582
1583         # Strip getstripe output to a space separated list of OSTs
1584         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1585                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1586         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1587                 error "stripes not on specified OSTs"
1588
1589         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1590 }
1591 run_test 27cc "two stripes on the same OST"
1592
1593 test_27cd() {
1594         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1595         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1596                 skip "server does not support overstriping"
1597         test_mkdir -p $DIR/$tdir
1598         local osts="0,1,1,0"
1599         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1600         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1601         echo "$getstripe"
1602
1603         # Strip getstripe output to a space separated list of OSTs
1604         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1605                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1606         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1607                 error "stripes not on specified OSTs"
1608
1609         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1610 }
1611 run_test 27cd "four stripes on two OSTs"
1612
1613 test_27ce() {
1614         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1615                 skip_env "too many osts, skipping"
1616         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1617                 skip "server does not support overstriping"
1618         # We do one more stripe than we have OSTs
1619         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1620                 skip_env "ea_inode feature disabled"
1621
1622         test_mkdir -p $DIR/$tdir
1623         local osts=""
1624         for i in $(seq 0 $OSTCOUNT);
1625         do
1626                 osts=$osts"0"
1627                 if [ $i -ne $OSTCOUNT ]; then
1628                         osts=$osts","
1629                 fi
1630         done
1631         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1632         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1633         echo "$getstripe"
1634
1635         # Strip getstripe output to a space separated list of OSTs
1636         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1637                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1638         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1639                 error "stripes not on specified OSTs"
1640
1641         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1642 }
1643 run_test 27ce "more stripes than OSTs with -o"
1644
1645 test_27cf() {
1646         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1647         local pid=0
1648
1649         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1650         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1651         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1652         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1653                 error "failed to set $osp_proc=0"
1654
1655         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1656         pid=$!
1657         sleep 1
1658         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1659         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1660                 error "failed to set $osp_proc=1"
1661         wait $pid
1662         [[ $pid -ne 0 ]] ||
1663                 error "should return error due to $osp_proc=0"
1664 }
1665 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1666
1667 test_27d() {
1668         test_mkdir $DIR/$tdir
1669         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1670                 error "setstripe failed"
1671         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1672         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1673 }
1674 run_test 27d "create file with default settings"
1675
1676 test_27e() {
1677         # LU-5839 adds check for existed layout before setting it
1678         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1679                 skip "Need MDS version at least 2.7.56"
1680
1681         test_mkdir $DIR/$tdir
1682         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1683         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1684         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1685 }
1686 run_test 27e "setstripe existing file (should return error)"
1687
1688 test_27f() {
1689         test_mkdir $DIR/$tdir
1690         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1691                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1692         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1693                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1694         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1695         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1696 }
1697 run_test 27f "setstripe with bad stripe size (should return error)"
1698
1699 test_27g() {
1700         test_mkdir $DIR/$tdir
1701         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1702         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1703                 error "$DIR/$tdir/$tfile has object"
1704 }
1705 run_test 27g "$LFS getstripe with no objects"
1706
1707 test_27ga() {
1708         test_mkdir $DIR/$tdir
1709         touch $DIR/$tdir/$tfile || error "touch failed"
1710         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1711         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1712         local rc=$?
1713         (( rc == 2 )) || error "getstripe did not return ENOENT"
1714 }
1715 run_test 27ga "$LFS getstripe with missing file (should return error)"
1716
1717 test_27i() {
1718         test_mkdir $DIR/$tdir
1719         touch $DIR/$tdir/$tfile || error "touch failed"
1720         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1721                 error "missing objects"
1722 }
1723 run_test 27i "$LFS getstripe with some objects"
1724
1725 test_27j() {
1726         test_mkdir $DIR/$tdir
1727         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1728                 error "setstripe failed" || true
1729 }
1730 run_test 27j "setstripe with bad stripe offset (should return error)"
1731
1732 test_27k() { # bug 2844
1733         test_mkdir $DIR/$tdir
1734         local file=$DIR/$tdir/$tfile
1735         local ll_max_blksize=$((4 * 1024 * 1024))
1736         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1737         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1738         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1739         dd if=/dev/zero of=$file bs=4k count=1
1740         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1741         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1742 }
1743 run_test 27k "limit i_blksize for broken user apps"
1744
1745 test_27l() {
1746         mcreate $DIR/$tfile || error "creating file"
1747         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1748                 error "setstripe should have failed" || true
1749 }
1750 run_test 27l "check setstripe permissions (should return error)"
1751
1752 test_27m() {
1753         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1754
1755         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1756                 skip_env "multiple clients -- skipping"
1757
1758         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1759                    head -n1)
1760         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1761                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1762         fi
1763         trap simple_cleanup_common EXIT
1764         test_mkdir $DIR/$tdir
1765         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1766         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1767                 error "dd should fill OST0"
1768         i=2
1769         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1770                 i=$((i + 1))
1771                 [ $i -gt 256 ] && break
1772         done
1773         i=$((i + 1))
1774         touch $DIR/$tdir/$tfile.$i
1775         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1776             awk '{print $1}'| grep -w "0") ] &&
1777                 error "OST0 was full but new created file still use it"
1778         i=$((i + 1))
1779         touch $DIR/$tdir/$tfile.$i
1780         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1781             awk '{print $1}'| grep -w "0") ] &&
1782                 error "OST0 was full but new created file still use it"
1783         simple_cleanup_common
1784 }
1785 run_test 27m "create file while OST0 was full"
1786
1787 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1788 # if the OST isn't full anymore.
1789 reset_enospc() {
1790         local ostidx=${1:-""}
1791         local delay
1792         local ready
1793         local get_prealloc
1794
1795         local list=$(comma_list $(osts_nodes))
1796         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1797
1798         do_nodes $list lctl set_param fail_loc=0
1799         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1800         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1801                 awk '{print $1 * 2;exit;}')
1802         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1803                         grep -v \"^0$\""
1804         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1805 }
1806
1807 __exhaust_precreations() {
1808         local OSTIDX=$1
1809         local FAILLOC=$2
1810         local FAILIDX=${3:-$OSTIDX}
1811         local ofacet=ost$((OSTIDX + 1))
1812
1813         test_mkdir -p -c1 $DIR/$tdir
1814         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1815         local mfacet=mds$((mdtidx + 1))
1816         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1817
1818         local OST=$(ostname_from_index $OSTIDX)
1819
1820         # on the mdt's osc
1821         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1822         local last_id=$(do_facet $mfacet lctl get_param -n \
1823                         osp.$mdtosc_proc1.prealloc_last_id)
1824         local next_id=$(do_facet $mfacet lctl get_param -n \
1825                         osp.$mdtosc_proc1.prealloc_next_id)
1826
1827         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1828         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1829
1830         test_mkdir -p $DIR/$tdir/${OST}
1831         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1832 #define OBD_FAIL_OST_ENOSPC              0x215
1833         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1834         echo "Creating to objid $last_id on ost $OST..."
1835         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1836         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1837         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1838 }
1839
1840 exhaust_precreations() {
1841         __exhaust_precreations $1 $2 $3
1842         sleep_maxage
1843 }
1844
1845 exhaust_all_precreations() {
1846         local i
1847         for (( i=0; i < OSTCOUNT; i++ )) ; do
1848                 __exhaust_precreations $i $1 -1
1849         done
1850         sleep_maxage
1851 }
1852
1853 test_27n() {
1854         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1856         remote_mds_nodsh && skip "remote MDS with nodsh"
1857         remote_ost_nodsh && skip "remote OST with nodsh"
1858
1859         reset_enospc
1860         rm -f $DIR/$tdir/$tfile
1861         exhaust_precreations 0 0x80000215
1862         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1863         touch $DIR/$tdir/$tfile || error "touch failed"
1864         $LFS getstripe $DIR/$tdir/$tfile
1865         reset_enospc
1866 }
1867 run_test 27n "create file with some full OSTs"
1868
1869 test_27o() {
1870         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1872         remote_mds_nodsh && skip "remote MDS with nodsh"
1873         remote_ost_nodsh && skip "remote OST with nodsh"
1874
1875         reset_enospc
1876         rm -f $DIR/$tdir/$tfile
1877         exhaust_all_precreations 0x215
1878
1879         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1880
1881         reset_enospc
1882         rm -rf $DIR/$tdir/*
1883 }
1884 run_test 27o "create file with all full OSTs (should error)"
1885
1886 test_27p() {
1887         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1889         remote_mds_nodsh && skip "remote MDS with nodsh"
1890         remote_ost_nodsh && skip "remote OST with nodsh"
1891
1892         reset_enospc
1893         rm -f $DIR/$tdir/$tfile
1894         test_mkdir $DIR/$tdir
1895
1896         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1897         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1898         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1899
1900         exhaust_precreations 0 0x80000215
1901         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1902         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1903         $LFS getstripe $DIR/$tdir/$tfile
1904
1905         reset_enospc
1906 }
1907 run_test 27p "append to a truncated file with some full OSTs"
1908
1909 test_27q() {
1910         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1912         remote_mds_nodsh && skip "remote MDS with nodsh"
1913         remote_ost_nodsh && skip "remote OST with nodsh"
1914
1915         reset_enospc
1916         rm -f $DIR/$tdir/$tfile
1917
1918         test_mkdir $DIR/$tdir
1919         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1920         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1921                 error "truncate $DIR/$tdir/$tfile failed"
1922         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1923
1924         exhaust_all_precreations 0x215
1925
1926         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1927         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1928
1929         reset_enospc
1930 }
1931 run_test 27q "append to truncated file with all OSTs full (should error)"
1932
1933 test_27r() {
1934         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1936         remote_mds_nodsh && skip "remote MDS with nodsh"
1937         remote_ost_nodsh && skip "remote OST with nodsh"
1938
1939         reset_enospc
1940         rm -f $DIR/$tdir/$tfile
1941         exhaust_precreations 0 0x80000215
1942
1943         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1944
1945         reset_enospc
1946 }
1947 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1948
1949 test_27s() { # bug 10725
1950         test_mkdir $DIR/$tdir
1951         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1952         local stripe_count=0
1953         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1954         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1955                 error "stripe width >= 2^32 succeeded" || true
1956
1957 }
1958 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1959
1960 test_27t() { # bug 10864
1961         WDIR=$(pwd)
1962         WLFS=$(which lfs)
1963         cd $DIR
1964         touch $tfile
1965         $WLFS getstripe $tfile
1966         cd $WDIR
1967 }
1968 run_test 27t "check that utils parse path correctly"
1969
1970 test_27u() { # bug 4900
1971         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1972         remote_mds_nodsh && skip "remote MDS with nodsh"
1973
1974         local index
1975         local list=$(comma_list $(mdts_nodes))
1976
1977 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1978         do_nodes $list $LCTL set_param fail_loc=0x139
1979         test_mkdir -p $DIR/$tdir
1980         trap simple_cleanup_common EXIT
1981         createmany -o $DIR/$tdir/t- 1000
1982         do_nodes $list $LCTL set_param fail_loc=0
1983
1984         TLOG=$TMP/$tfile.getstripe
1985         $LFS getstripe $DIR/$tdir > $TLOG
1986         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1987         unlinkmany $DIR/$tdir/t- 1000
1988         trap 0
1989         [[ $OBJS -gt 0 ]] &&
1990                 error "$OBJS objects created on OST-0. See $TLOG" ||
1991                 rm -f $TLOG
1992 }
1993 run_test 27u "skip object creation on OSC w/o objects"
1994
1995 test_27v() { # bug 4900
1996         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1998         remote_mds_nodsh && skip "remote MDS with nodsh"
1999         remote_ost_nodsh && skip "remote OST with nodsh"
2000
2001         exhaust_all_precreations 0x215
2002         reset_enospc
2003
2004         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2005
2006         touch $DIR/$tdir/$tfile
2007         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2008         # all except ost1
2009         for (( i=1; i < OSTCOUNT; i++ )); do
2010                 do_facet ost$i lctl set_param fail_loc=0x705
2011         done
2012         local START=`date +%s`
2013         createmany -o $DIR/$tdir/$tfile 32
2014
2015         local FINISH=`date +%s`
2016         local TIMEOUT=`lctl get_param -n timeout`
2017         local PROCESS=$((FINISH - START))
2018         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2019                error "$FINISH - $START >= $TIMEOUT / 2"
2020         sleep $((TIMEOUT / 2 - PROCESS))
2021         reset_enospc
2022 }
2023 run_test 27v "skip object creation on slow OST"
2024
2025 test_27w() { # bug 10997
2026         test_mkdir $DIR/$tdir
2027         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2028         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2029                 error "stripe size $size != 65536" || true
2030         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2031                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2032 }
2033 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2034
2035 test_27wa() {
2036         [[ $OSTCOUNT -lt 2 ]] &&
2037                 skip_env "skipping multiple stripe count/offset test"
2038
2039         test_mkdir $DIR/$tdir
2040         for i in $(seq 1 $OSTCOUNT); do
2041                 offset=$((i - 1))
2042                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2043                         error "setstripe -c $i -i $offset failed"
2044                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2045                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2046                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2047                 [ $index -ne $offset ] &&
2048                         error "stripe offset $index != $offset" || true
2049         done
2050 }
2051 run_test 27wa "check $LFS setstripe -c -i options"
2052
2053 test_27x() {
2054         remote_ost_nodsh && skip "remote OST with nodsh"
2055         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2057
2058         OFFSET=$(($OSTCOUNT - 1))
2059         OSTIDX=0
2060         local OST=$(ostname_from_index $OSTIDX)
2061
2062         test_mkdir $DIR/$tdir
2063         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2064         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2065         sleep_maxage
2066         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2067         for i in $(seq 0 $OFFSET); do
2068                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2069                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2070                 error "OST0 was degraded but new created file still use it"
2071         done
2072         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2073 }
2074 run_test 27x "create files while OST0 is degraded"
2075
2076 test_27y() {
2077         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2078         remote_mds_nodsh && skip "remote MDS with nodsh"
2079         remote_ost_nodsh && skip "remote OST with nodsh"
2080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2081
2082         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2083         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2084                 osp.$mdtosc.prealloc_last_id)
2085         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2086                 osp.$mdtosc.prealloc_next_id)
2087         local fcount=$((last_id - next_id))
2088         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2089         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2090
2091         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2092                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2093         local OST_DEACTIVE_IDX=-1
2094         local OSC
2095         local OSTIDX
2096         local OST
2097
2098         for OSC in $MDS_OSCS; do
2099                 OST=$(osc_to_ost $OSC)
2100                 OSTIDX=$(index_from_ostuuid $OST)
2101                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2102                         OST_DEACTIVE_IDX=$OSTIDX
2103                 fi
2104                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2105                         echo $OSC "is Deactivated:"
2106                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2107                 fi
2108         done
2109
2110         OSTIDX=$(index_from_ostuuid $OST)
2111         test_mkdir $DIR/$tdir
2112         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2113
2114         for OSC in $MDS_OSCS; do
2115                 OST=$(osc_to_ost $OSC)
2116                 OSTIDX=$(index_from_ostuuid $OST)
2117                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2118                         echo $OST "is degraded:"
2119                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2120                                                 obdfilter.$OST.degraded=1
2121                 fi
2122         done
2123
2124         sleep_maxage
2125         createmany -o $DIR/$tdir/$tfile $fcount
2126
2127         for OSC in $MDS_OSCS; do
2128                 OST=$(osc_to_ost $OSC)
2129                 OSTIDX=$(index_from_ostuuid $OST)
2130                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2131                         echo $OST "is recovered from degraded:"
2132                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2133                                                 obdfilter.$OST.degraded=0
2134                 else
2135                         do_facet $SINGLEMDS lctl --device %$OSC activate
2136                 fi
2137         done
2138
2139         # all osp devices get activated, hence -1 stripe count restored
2140         local stripe_count=0
2141
2142         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2143         # devices get activated.
2144         sleep_maxage
2145         $LFS setstripe -c -1 $DIR/$tfile
2146         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2147         rm -f $DIR/$tfile
2148         [ $stripe_count -ne $OSTCOUNT ] &&
2149                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2150         return 0
2151 }
2152 run_test 27y "create files while OST0 is degraded and the rest inactive"
2153
2154 check_seq_oid()
2155 {
2156         log "check file $1"
2157
2158         lmm_count=$($LFS getstripe -c $1)
2159         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2160         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2161
2162         local old_ifs="$IFS"
2163         IFS=$'[:]'
2164         fid=($($LFS path2fid $1))
2165         IFS="$old_ifs"
2166
2167         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2168         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2169
2170         # compare lmm_seq and lu_fid->f_seq
2171         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2172         # compare lmm_object_id and lu_fid->oid
2173         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2174
2175         # check the trusted.fid attribute of the OST objects of the file
2176         local have_obdidx=false
2177         local stripe_nr=0
2178         $LFS getstripe $1 | while read obdidx oid hex seq; do
2179                 # skip lines up to and including "obdidx"
2180                 [ -z "$obdidx" ] && break
2181                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2182                 $have_obdidx || continue
2183
2184                 local ost=$((obdidx + 1))
2185                 local dev=$(ostdevname $ost)
2186                 local oid_hex
2187
2188                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2189
2190                 seq=$(echo $seq | sed -e "s/^0x//g")
2191                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2192                         oid_hex=$(echo $oid)
2193                 else
2194                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2195                 fi
2196                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2197
2198                 local ff=""
2199                 #
2200                 # Don't unmount/remount the OSTs if we don't need to do that.
2201                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2202                 # update too, until that use mount/ll_decode_filter_fid/mount.
2203                 # Re-enable when debugfs will understand new filter_fid.
2204                 #
2205                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2206                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2207                                 $dev 2>/dev/null" | grep "parent=")
2208                 fi
2209                 if [ -z "$ff" ]; then
2210                         stop ost$ost
2211                         mount_fstype ost$ost
2212                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2213                                 $(facet_mntpt ost$ost)/$obj_file)
2214                         unmount_fstype ost$ost
2215                         start ost$ost $dev $OST_MOUNT_OPTS
2216                         clients_up
2217                 fi
2218
2219                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2220
2221                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2222
2223                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2224                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2225                 #
2226                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2227                 #       stripe_size=1048576 component_id=1 component_start=0 \
2228                 #       component_end=33554432
2229                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2230                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2231                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2232                 local ff_pstripe
2233                 if grep -q 'stripe=' <<<$ff; then
2234                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2235                 else
2236                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2237                         # into f_ver in this case.  See comment on ff_parent.
2238                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2239                 fi
2240
2241                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2242                 [ $ff_pseq = $lmm_seq ] ||
2243                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2244                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2245                 [ $ff_poid = $lmm_oid ] ||
2246                         error "FF parent OID $ff_poid != $lmm_oid"
2247                 (($ff_pstripe == $stripe_nr)) ||
2248                         error "FF stripe $ff_pstripe != $stripe_nr"
2249
2250                 stripe_nr=$((stripe_nr + 1))
2251                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2252                         continue
2253                 if grep -q 'stripe_count=' <<<$ff; then
2254                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2255                                             -e 's/ .*//' <<<$ff)
2256                         [ $lmm_count = $ff_scnt ] ||
2257                                 error "FF stripe count $lmm_count != $ff_scnt"
2258                 fi
2259         done
2260 }
2261
2262 test_27z() {
2263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2264         remote_ost_nodsh && skip "remote OST with nodsh"
2265
2266         test_mkdir $DIR/$tdir
2267         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2268                 { error "setstripe -c -1 failed"; return 1; }
2269         # We need to send a write to every object to get parent FID info set.
2270         # This _should_ also work for setattr, but does not currently.
2271         # touch $DIR/$tdir/$tfile-1 ||
2272         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2273                 { error "dd $tfile-1 failed"; return 2; }
2274         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2275                 { error "setstripe -c -1 failed"; return 3; }
2276         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2277                 { error "dd $tfile-2 failed"; return 4; }
2278
2279         # make sure write RPCs have been sent to OSTs
2280         sync; sleep 5; sync
2281
2282         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2283         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2284 }
2285 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2286
2287 test_27A() { # b=19102
2288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2289
2290         save_layout_restore_at_exit $MOUNT
2291         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2292         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2293                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2294         local default_size=$($LFS getstripe -S $MOUNT)
2295         local default_offset=$($LFS getstripe -i $MOUNT)
2296         local dsize=$(do_facet $SINGLEMDS \
2297                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2298         [ $default_size -eq $dsize ] ||
2299                 error "stripe size $default_size != $dsize"
2300         [ $default_offset -eq -1 ] ||
2301                 error "stripe offset $default_offset != -1"
2302 }
2303 run_test 27A "check filesystem-wide default LOV EA values"
2304
2305 test_27B() { # LU-2523
2306         test_mkdir $DIR/$tdir
2307         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2308         touch $DIR/$tdir/f0
2309         # open f1 with O_LOV_DELAY_CREATE
2310         # rename f0 onto f1
2311         # call setstripe ioctl on open file descriptor for f1
2312         # close
2313         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2314                 $DIR/$tdir/f0
2315
2316         rm -f $DIR/$tdir/f1
2317         # open f1 with O_LOV_DELAY_CREATE
2318         # unlink f1
2319         # call setstripe ioctl on open file descriptor for f1
2320         # close
2321         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2322
2323         # Allow multiop to fail in imitation of NFS's busted semantics.
2324         true
2325 }
2326 run_test 27B "call setstripe on open unlinked file/rename victim"
2327
2328 # 27C family tests full striping and overstriping
2329 test_27Ca() { #LU-2871
2330         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2331
2332         declare -a ost_idx
2333         local index
2334         local found
2335         local i
2336         local j
2337
2338         test_mkdir $DIR/$tdir
2339         cd $DIR/$tdir
2340         for i in $(seq 0 $((OSTCOUNT - 1))); do
2341                 # set stripe across all OSTs starting from OST$i
2342                 $LFS setstripe -i $i -c -1 $tfile$i
2343                 # get striping information
2344                 ost_idx=($($LFS getstripe $tfile$i |
2345                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2346                 echo ${ost_idx[@]}
2347
2348                 # check the layout
2349                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2350                         error "${#ost_idx[@]} != $OSTCOUNT"
2351
2352                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2353                         found=0
2354                         for j in $(echo ${ost_idx[@]}); do
2355                                 if [ $index -eq $j ]; then
2356                                         found=1
2357                                         break
2358                                 fi
2359                         done
2360                         [ $found = 1 ] ||
2361                                 error "Can not find $index in ${ost_idx[@]}"
2362                 done
2363         done
2364 }
2365 run_test 27Ca "check full striping across all OSTs"
2366
2367 test_27Cb() {
2368         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2369                 skip "server does not support overstriping"
2370         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2371                 skip_env "too many osts, skipping"
2372
2373         test_mkdir -p $DIR/$tdir
2374         local setcount=$(($OSTCOUNT * 2))
2375         [ $setcount -ge 160 ] || large_xattr_enabled ||
2376                 skip_env "ea_inode feature disabled"
2377
2378         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2379                 error "setstripe failed"
2380
2381         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2382         [ $count -eq $setcount ] ||
2383                 error "stripe count $count, should be $setcount"
2384
2385         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2386                 error "overstriped should be set in pattern"
2387
2388         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2389                 error "dd failed"
2390 }
2391 run_test 27Cb "more stripes than OSTs with -C"
2392
2393 test_27Cc() {
2394         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2395                 skip "server does not support overstriping"
2396         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2397
2398         test_mkdir -p $DIR/$tdir
2399         local setcount=$(($OSTCOUNT - 1))
2400
2401         [ $setcount -ge 160 ] || large_xattr_enabled ||
2402                 skip_env "ea_inode feature disabled"
2403
2404         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2405                 error "setstripe failed"
2406
2407         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2408         [ $count -eq $setcount ] ||
2409                 error "stripe count $count, should be $setcount"
2410
2411         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2412                 error "overstriped should not be set in pattern"
2413
2414         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2415                 error "dd failed"
2416 }
2417 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2418
2419 test_27Cd() {
2420         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2421                 skip "server does not support overstriping"
2422         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2423         large_xattr_enabled || skip_env "ea_inode feature disabled"
2424
2425         test_mkdir -p $DIR/$tdir
2426         local setcount=$LOV_MAX_STRIPE_COUNT
2427
2428         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2429                 error "setstripe failed"
2430
2431         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2432         [ $count -eq $setcount ] ||
2433                 error "stripe count $count, should be $setcount"
2434
2435         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2436                 error "overstriped should be set in pattern"
2437
2438         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2439                 error "dd failed"
2440
2441         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2442 }
2443 run_test 27Cd "test maximum stripe count"
2444
2445 test_27Ce() {
2446         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2447                 skip "server does not support overstriping"
2448         test_mkdir -p $DIR/$tdir
2449
2450         pool_add $TESTNAME || error "Pool creation failed"
2451         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2452
2453         local setcount=8
2454
2455         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2456                 error "setstripe failed"
2457
2458         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2459         [ $count -eq $setcount ] ||
2460                 error "stripe count $count, should be $setcount"
2461
2462         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2463                 error "overstriped should be set in pattern"
2464
2465         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2466                 error "dd failed"
2467
2468         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2469 }
2470 run_test 27Ce "test pool with overstriping"
2471
2472 test_27Cf() {
2473         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2474                 skip "server does not support overstriping"
2475         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2476                 skip_env "too many osts, skipping"
2477
2478         test_mkdir -p $DIR/$tdir
2479
2480         local setcount=$(($OSTCOUNT * 2))
2481         [ $setcount -ge 160 ] || large_xattr_enabled ||
2482                 skip_env "ea_inode feature disabled"
2483
2484         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2485                 error "setstripe failed"
2486
2487         echo 1 > $DIR/$tdir/$tfile
2488
2489         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2490         [ $count -eq $setcount ] ||
2491                 error "stripe count $count, should be $setcount"
2492
2493         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2494                 error "overstriped should be set in pattern"
2495
2496         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2497                 error "dd failed"
2498
2499         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2500 }
2501 run_test 27Cf "test default inheritance with overstriping"
2502
2503 test_27D() {
2504         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2505         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2506         remote_mds_nodsh && skip "remote MDS with nodsh"
2507
2508         local POOL=${POOL:-testpool}
2509         local first_ost=0
2510         local last_ost=$(($OSTCOUNT - 1))
2511         local ost_step=1
2512         local ost_list=$(seq $first_ost $ost_step $last_ost)
2513         local ost_range="$first_ost $last_ost $ost_step"
2514
2515         test_mkdir $DIR/$tdir
2516         pool_add $POOL || error "pool_add failed"
2517         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2518
2519         local skip27D
2520         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2521                 skip27D+="-s 29"
2522         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2523                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2524                         skip27D+=" -s 30,31"
2525         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2526           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2527                 skip27D+=" -s 32,33"
2528         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2529                 skip27D+=" -s 34"
2530         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2531                 error "llapi_layout_test failed"
2532
2533         destroy_test_pools || error "destroy test pools failed"
2534 }
2535 run_test 27D "validate llapi_layout API"
2536
2537 # Verify that default_easize is increased from its initial value after
2538 # accessing a widely striped file.
2539 test_27E() {
2540         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2541         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2542                 skip "client does not have LU-3338 fix"
2543
2544         # 72 bytes is the minimum space required to store striping
2545         # information for a file striped across one OST:
2546         # (sizeof(struct lov_user_md_v3) +
2547         #  sizeof(struct lov_user_ost_data_v1))
2548         local min_easize=72
2549         $LCTL set_param -n llite.*.default_easize $min_easize ||
2550                 error "lctl set_param failed"
2551         local easize=$($LCTL get_param -n llite.*.default_easize)
2552
2553         [ $easize -eq $min_easize ] ||
2554                 error "failed to set default_easize"
2555
2556         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2557                 error "setstripe failed"
2558         # In order to ensure stat() call actually talks to MDS we need to
2559         # do something drastic to this file to shake off all lock, e.g.
2560         # rename it (kills lookup lock forcing cache cleaning)
2561         mv $DIR/$tfile $DIR/${tfile}-1
2562         ls -l $DIR/${tfile}-1
2563         rm $DIR/${tfile}-1
2564
2565         easize=$($LCTL get_param -n llite.*.default_easize)
2566
2567         [ $easize -gt $min_easize ] ||
2568                 error "default_easize not updated"
2569 }
2570 run_test 27E "check that default extended attribute size properly increases"
2571
2572 test_27F() { # LU-5346/LU-7975
2573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2574         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2575         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2576                 skip "Need MDS version at least 2.8.51"
2577         remote_ost_nodsh && skip "remote OST with nodsh"
2578
2579         test_mkdir $DIR/$tdir
2580         rm -f $DIR/$tdir/f0
2581         $LFS setstripe -c 2 $DIR/$tdir
2582
2583         # stop all OSTs to reproduce situation for LU-7975 ticket
2584         for num in $(seq $OSTCOUNT); do
2585                 stop ost$num
2586         done
2587
2588         # open/create f0 with O_LOV_DELAY_CREATE
2589         # truncate f0 to a non-0 size
2590         # close
2591         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2592
2593         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2594         # open/write it again to force delayed layout creation
2595         cat /etc/hosts > $DIR/$tdir/f0 &
2596         catpid=$!
2597
2598         # restart OSTs
2599         for num in $(seq $OSTCOUNT); do
2600                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2601                         error "ost$num failed to start"
2602         done
2603
2604         wait $catpid || error "cat failed"
2605
2606         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2607         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2608                 error "wrong stripecount"
2609
2610 }
2611 run_test 27F "Client resend delayed layout creation with non-zero size"
2612
2613 test_27G() { #LU-10629
2614         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2615                 skip "Need MDS version at least 2.11.51"
2616         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2617         remote_mds_nodsh && skip "remote MDS with nodsh"
2618         local POOL=${POOL:-testpool}
2619         local ostrange="0 0 1"
2620
2621         test_mkdir $DIR/$tdir
2622         touch $DIR/$tdir/$tfile.nopool
2623         pool_add $POOL || error "pool_add failed"
2624         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2625         $LFS setstripe -p $POOL $DIR/$tdir
2626
2627         local pool=$($LFS getstripe -p $DIR/$tdir)
2628
2629         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2630         touch $DIR/$tdir/$tfile.default
2631         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2632         $LFS find $DIR/$tdir -type f --pool $POOL
2633         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2634         [[ "$found" == "2" ]] ||
2635                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2636
2637         $LFS setstripe -d $DIR/$tdir
2638
2639         pool=$($LFS getstripe -p -d $DIR/$tdir)
2640
2641         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2642 }
2643 run_test 27G "Clear OST pool from stripe"
2644
2645 test_27H() {
2646         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2647                 skip "Need MDS version newer than 2.11.54"
2648         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2649         test_mkdir $DIR/$tdir
2650         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2651         touch $DIR/$tdir/$tfile
2652         $LFS getstripe -c $DIR/$tdir/$tfile
2653         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2654                 error "two-stripe file doesn't have two stripes"
2655
2656         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2657         $LFS getstripe -y $DIR/$tdir/$tfile
2658         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2659              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2660                 error "expected l_ost_idx: [02]$ not matched"
2661
2662         # make sure ost list has been cleared
2663         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2664         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2665                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2666         touch $DIR/$tdir/f3
2667         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2668 }
2669 run_test 27H "Set specific OSTs stripe"
2670
2671 test_27I() {
2672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2673         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2674         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2675                 skip "Need MDS version newer than 2.12.52"
2676         local pool=$TESTNAME
2677         local ostrange="1 1 1"
2678
2679         save_layout_restore_at_exit $MOUNT
2680         $LFS setstripe -c 2 -i 0 $MOUNT
2681         pool_add $pool || error "pool_add failed"
2682         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2683         test_mkdir $DIR/$tdir
2684         $LFS setstripe -p $pool $DIR/$tdir
2685         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2686         $LFS getstripe $DIR/$tdir/$tfile
2687 }
2688 run_test 27I "check that root dir striping does not break parent dir one"
2689
2690 test_27J() {
2691         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2692                 skip "Need MDS version newer than 2.12.51"
2693
2694         test_mkdir $DIR/$tdir
2695         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2696         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2697
2698         # create foreign file (raw way)
2699         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2700                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2701
2702         # verify foreign file (raw way)
2703         parse_foreign_file -f $DIR/$tdir/$tfile |
2704                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2705                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2706         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2707                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2708         parse_foreign_file -f $DIR/$tdir/$tfile |
2709                 grep "lov_foreign_size: 73" ||
2710                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2711         parse_foreign_file -f $DIR/$tdir/$tfile |
2712                 grep "lov_foreign_type: 1" ||
2713                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2714         parse_foreign_file -f $DIR/$tdir/$tfile |
2715                 grep "lov_foreign_flags: 0x0000DA08" ||
2716                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2717         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2718                 grep "lov_foreign_value: 0x" |
2719                 sed -e 's/lov_foreign_value: 0x//')
2720         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2721         [[ $lov = ${lov2// /} ]] ||
2722                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2723
2724         # create foreign file (lfs + API)
2725         $LFS setstripe --foreign=daos --flags 0xda08 \
2726                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2727                 error "$DIR/$tdir/${tfile}2: create failed"
2728
2729         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2730                 grep "lfm_magic:.*0x0BD70BD0" ||
2731                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2732         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2733         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2734                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2735         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2736                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2737         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2738                 grep "lfm_flags:.*0x0000DA08" ||
2739                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2740         $LFS getstripe $DIR/$tdir/${tfile}2 |
2741                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2742                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2743
2744         # modify striping should fail
2745         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2746                 error "$DIR/$tdir/$tfile: setstripe should fail"
2747         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2748                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2749
2750         # R/W should fail
2751         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2752         cat $DIR/$tdir/${tfile}2 &&
2753                 error "$DIR/$tdir/${tfile}2: read should fail"
2754         cat /etc/passwd > $DIR/$tdir/$tfile &&
2755                 error "$DIR/$tdir/$tfile: write should fail"
2756         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2757                 error "$DIR/$tdir/${tfile}2: write should fail"
2758
2759         # chmod should work
2760         chmod 222 $DIR/$tdir/$tfile ||
2761                 error "$DIR/$tdir/$tfile: chmod failed"
2762         chmod 222 $DIR/$tdir/${tfile}2 ||
2763                 error "$DIR/$tdir/${tfile}2: chmod failed"
2764
2765         # chown should work
2766         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2767                 error "$DIR/$tdir/$tfile: chown failed"
2768         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2769                 error "$DIR/$tdir/${tfile}2: chown failed"
2770
2771         # rename should work
2772         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2773                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2774         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2775                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2776
2777         #remove foreign file
2778         rm $DIR/$tdir/${tfile}.new ||
2779                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2780         rm $DIR/$tdir/${tfile}2.new ||
2781                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2782 }
2783 run_test 27J "basic ops on file with foreign LOV"
2784
2785 test_27K() {
2786         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2787                 skip "Need MDS version newer than 2.12.49"
2788
2789         test_mkdir $DIR/$tdir
2790         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2791         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2792
2793         # create foreign dir (raw way)
2794         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2795                 error "create_foreign_dir FAILED"
2796
2797         # verify foreign dir (raw way)
2798         parse_foreign_dir -d $DIR/$tdir/$tdir |
2799                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2800                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2801         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2802                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2803         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2804                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2805         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2806                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2807         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2808                 grep "lmv_foreign_value: 0x" |
2809                 sed 's/lmv_foreign_value: 0x//')
2810         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2811                 sed 's/ //g')
2812         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2813
2814         # create foreign dir (lfs + API)
2815         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2816                 $DIR/$tdir/${tdir}2 ||
2817                 error "$DIR/$tdir/${tdir}2: create failed"
2818
2819         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2820                 grep "lfm_magic:.*0x0CD50CD0" ||
2821                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2822         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2823         # - sizeof(lfm_type) - sizeof(lfm_flags)
2824         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2825                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2826         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2827                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2828         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2829                 grep "lfm_flags:.*0x0000DA05" ||
2830                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2831         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2832                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2833                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2834
2835         # file create in dir should fail
2836         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2837         touch $DIR/$tdir/${tdir}2/$tfile &&
2838                 "$DIR/${tdir}2: file create should fail"
2839
2840         # chmod should work
2841         chmod 777 $DIR/$tdir/$tdir ||
2842                 error "$DIR/$tdir: chmod failed"
2843         chmod 777 $DIR/$tdir/${tdir}2 ||
2844                 error "$DIR/${tdir}2: chmod failed"
2845
2846         # chown should work
2847         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2848                 error "$DIR/$tdir: chown failed"
2849         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2850                 error "$DIR/${tdir}2: chown failed"
2851
2852         # rename should work
2853         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2854                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2855         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2856                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2857
2858         #remove foreign dir
2859         rmdir $DIR/$tdir/${tdir}.new ||
2860                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2861         rmdir $DIR/$tdir/${tdir}2.new ||
2862                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2863 }
2864 run_test 27K "basic ops on dir with foreign LMV"
2865
2866 test_27L() {
2867         remote_mds_nodsh && skip "remote MDS with nodsh"
2868
2869         local POOL=${POOL:-$TESTNAME}
2870
2871         pool_add $POOL || error "pool_add failed"
2872
2873         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2874                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2875                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2876 }
2877 run_test 27L "lfs pool_list gives correct pool name"
2878
2879 test_27M() {
2880         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2881                 skip "Need MDS version >= than 2.12.57"
2882         remote_mds_nodsh && skip "remote MDS with nodsh"
2883         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2884
2885         test_mkdir $DIR/$tdir
2886
2887         # Set default striping on directory
2888         $LFS setstripe -C 4 $DIR/$tdir
2889
2890         echo 1 > $DIR/$tdir/${tfile}.1
2891         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2892         local setcount=4
2893         [ $count -eq $setcount ] ||
2894                 error "(1) stripe count $count, should be $setcount"
2895
2896         # Capture existing append_stripe_count setting for restore
2897         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2898         local mdts=$(comma_list $(mdts_nodes))
2899         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2900
2901         local appendcount=$orig_count
2902         echo 1 >> $DIR/$tdir/${tfile}.2_append
2903         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2904         [ $count -eq $appendcount ] ||
2905                 error "(2)stripe count $count, should be $appendcount for append"
2906
2907         # Disable O_APPEND striping, verify it works
2908         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2909
2910         # Should now get the default striping, which is 4
2911         setcount=4
2912         echo 1 >> $DIR/$tdir/${tfile}.3_append
2913         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2914         [ $count -eq $setcount ] ||
2915                 error "(3) stripe count $count, should be $setcount"
2916
2917         # Try changing the stripe count for append files
2918         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2919
2920         # Append striping is now 2 (directory default is still 4)
2921         appendcount=2
2922         echo 1 >> $DIR/$tdir/${tfile}.4_append
2923         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2924         [ $count -eq $appendcount ] ||
2925                 error "(4) stripe count $count, should be $appendcount for append"
2926
2927         # Test append stripe count of -1
2928         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2929         appendcount=$OSTCOUNT
2930         echo 1 >> $DIR/$tdir/${tfile}.5
2931         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2932         [ $count -eq $appendcount ] ||
2933                 error "(5) stripe count $count, should be $appendcount for append"
2934
2935         # Set append striping back to default of 1
2936         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2937
2938         # Try a new default striping, PFL + DOM
2939         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2940
2941         # Create normal DOM file, DOM returns stripe count == 0
2942         setcount=0
2943         touch $DIR/$tdir/${tfile}.6
2944         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2945         [ $count -eq $setcount ] ||
2946                 error "(6) stripe count $count, should be $setcount"
2947
2948         # Show
2949         appendcount=1
2950         echo 1 >> $DIR/$tdir/${tfile}.7_append
2951         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2952         [ $count -eq $appendcount ] ||
2953                 error "(7) stripe count $count, should be $appendcount for append"
2954
2955         # Clean up DOM layout
2956         $LFS setstripe -d $DIR/$tdir
2957
2958         # Now test that append striping works when layout is from root
2959         $LFS setstripe -c 2 $MOUNT
2960         # Make a special directory for this
2961         mkdir $DIR/${tdir}/${tdir}.2
2962         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2963
2964         # Verify for normal file
2965         setcount=2
2966         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2967         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2968         [ $count -eq $setcount ] ||
2969                 error "(8) stripe count $count, should be $setcount"
2970
2971         appendcount=1
2972         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2973         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2974         [ $count -eq $appendcount ] ||
2975                 error "(9) stripe count $count, should be $appendcount for append"
2976
2977         # Now test O_APPEND striping with pools
2978         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
2979         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
2980
2981         # Create the pool
2982         pool_add $TESTNAME || error "pool creation failed"
2983         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
2984
2985         echo 1 >> $DIR/$tdir/${tfile}.10_append
2986
2987         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
2988         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
2989
2990         # Check that count is still correct
2991         appendcount=1
2992         echo 1 >> $DIR/$tdir/${tfile}.11_append
2993         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
2994         [ $count -eq $appendcount ] ||
2995                 error "(11) stripe count $count, should be $appendcount for append"
2996
2997         # Disable O_APPEND stripe count, verify pool works separately
2998         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2999
3000         echo 1 >> $DIR/$tdir/${tfile}.12_append
3001
3002         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3003         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3004
3005         # Remove pool setting, verify it's not applied
3006         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3007
3008         echo 1 >> $DIR/$tdir/${tfile}.13_append
3009
3010         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3011         [ "$pool" = "" ] || error "(13) pool found: $pool"
3012 }
3013 run_test 27M "test O_APPEND striping"
3014
3015 test_27N() {
3016         combined_mgs_mds && skip "needs separate MGS/MDT"
3017
3018         pool_add $TESTNAME || error "pool_add failed"
3019         do_facet mgs "$LCTL pool_list $FSNAME" |
3020                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3021                 error "lctl pool_list on MGS failed"
3022 }
3023 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3024
3025 # createtest also checks that device nodes are created and
3026 # then visible correctly (#2091)
3027 test_28() { # bug 2091
3028         test_mkdir $DIR/d28
3029         $CREATETEST $DIR/d28/ct || error "createtest failed"
3030 }
3031 run_test 28 "create/mknod/mkdir with bad file types ============"
3032
3033 test_29() {
3034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3035
3036         sync; sleep 1; sync # flush out any dirty pages from previous tests
3037         cancel_lru_locks
3038         test_mkdir $DIR/d29
3039         touch $DIR/d29/foo
3040         log 'first d29'
3041         ls -l $DIR/d29
3042
3043         declare -i LOCKCOUNTORIG=0
3044         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3045                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3046         done
3047         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3048
3049         declare -i LOCKUNUSEDCOUNTORIG=0
3050         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3051                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3052         done
3053
3054         log 'second d29'
3055         ls -l $DIR/d29
3056         log 'done'
3057
3058         declare -i LOCKCOUNTCURRENT=0
3059         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3060                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3061         done
3062
3063         declare -i LOCKUNUSEDCOUNTCURRENT=0
3064         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3065                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3066         done
3067
3068         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3069                 $LCTL set_param -n ldlm.dump_namespaces ""
3070                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3071                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3072                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3073                 return 2
3074         fi
3075         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3076                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3077                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3078                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3079                 return 3
3080         fi
3081 }
3082 run_test 29 "IT_GETATTR regression  ============================"
3083
3084 test_30a() { # was test_30
3085         cp $(which ls) $DIR || cp /bin/ls $DIR
3086         $DIR/ls / || error "Can't execute binary from lustre"
3087         rm $DIR/ls
3088 }
3089 run_test 30a "execute binary from Lustre (execve) =============="
3090
3091 test_30b() {
3092         cp `which ls` $DIR || cp /bin/ls $DIR
3093         chmod go+rx $DIR/ls
3094         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3095         rm $DIR/ls
3096 }
3097 run_test 30b "execute binary from Lustre as non-root ==========="
3098
3099 test_30c() { # b=22376
3100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3101
3102         cp $(which ls) $DIR || cp /bin/ls $DIR
3103         chmod a-rw $DIR/ls
3104         cancel_lru_locks mdc
3105         cancel_lru_locks osc
3106         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3107         rm -f $DIR/ls
3108 }
3109 run_test 30c "execute binary from Lustre without read perms ===="
3110
3111 test_30d() {
3112         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3113
3114         for i in {1..10}; do
3115                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3116                 local PID=$!
3117                 sleep 1
3118                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3119                 wait $PID || error "executing dd from Lustre failed"
3120                 rm -f $DIR/$tfile
3121         done
3122
3123         rm -f $DIR/dd
3124 }
3125 run_test 30d "execute binary from Lustre while clear locks"
3126
3127 test_31a() {
3128         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3129         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3130 }
3131 run_test 31a "open-unlink file =================================="
3132
3133 test_31b() {
3134         touch $DIR/f31 || error "touch $DIR/f31 failed"
3135         ln $DIR/f31 $DIR/f31b || error "ln failed"
3136         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3137         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3138 }
3139 run_test 31b "unlink file with multiple links while open ======="
3140
3141 test_31c() {
3142         touch $DIR/f31 || error "touch $DIR/f31 failed"
3143         ln $DIR/f31 $DIR/f31c || error "ln failed"
3144         multiop_bg_pause $DIR/f31 O_uc ||
3145                 error "multiop_bg_pause for $DIR/f31 failed"
3146         MULTIPID=$!
3147         $MULTIOP $DIR/f31c Ouc
3148         kill -USR1 $MULTIPID
3149         wait $MULTIPID
3150 }
3151 run_test 31c "open-unlink file with multiple links ============="
3152
3153 test_31d() {
3154         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3155         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3156 }
3157 run_test 31d "remove of open directory ========================="
3158
3159 test_31e() { # bug 2904
3160         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3161 }
3162 run_test 31e "remove of open non-empty directory ==============="
3163
3164 test_31f() { # bug 4554
3165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3166
3167         set -vx
3168         test_mkdir $DIR/d31f
3169         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3170         cp /etc/hosts $DIR/d31f
3171         ls -l $DIR/d31f
3172         $LFS getstripe $DIR/d31f/hosts
3173         multiop_bg_pause $DIR/d31f D_c || return 1
3174         MULTIPID=$!
3175
3176         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3177         test_mkdir $DIR/d31f
3178         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3179         cp /etc/hosts $DIR/d31f
3180         ls -l $DIR/d31f
3181         $LFS getstripe $DIR/d31f/hosts
3182         multiop_bg_pause $DIR/d31f D_c || return 1
3183         MULTIPID2=$!
3184
3185         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3186         wait $MULTIPID || error "first opendir $MULTIPID failed"
3187
3188         sleep 6
3189
3190         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3191         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3192         set +vx
3193 }
3194 run_test 31f "remove of open directory with open-unlink file ==="
3195
3196 test_31g() {
3197         echo "-- cross directory link --"
3198         test_mkdir -c1 $DIR/${tdir}ga
3199         test_mkdir -c1 $DIR/${tdir}gb
3200         touch $DIR/${tdir}ga/f
3201         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3202         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3203         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3204         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3205         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3206 }
3207 run_test 31g "cross directory link==============="
3208
3209 test_31h() {
3210         echo "-- cross directory link --"
3211         test_mkdir -c1 $DIR/${tdir}
3212         test_mkdir -c1 $DIR/${tdir}/dir
3213         touch $DIR/${tdir}/f
3214         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3215         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3216         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3217         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3218         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3219 }
3220 run_test 31h "cross directory link under child==============="
3221
3222 test_31i() {
3223         echo "-- cross directory link --"
3224         test_mkdir -c1 $DIR/$tdir
3225         test_mkdir -c1 $DIR/$tdir/dir
3226         touch $DIR/$tdir/dir/f
3227         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3228         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3229         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3230         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3231         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3232 }
3233 run_test 31i "cross directory link under parent==============="
3234
3235 test_31j() {
3236         test_mkdir -c1 -p $DIR/$tdir
3237         test_mkdir -c1 -p $DIR/$tdir/dir1
3238         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3239         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3240         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3241         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3242         return 0
3243 }
3244 run_test 31j "link for directory==============="
3245
3246 test_31k() {
3247         test_mkdir -c1 -p $DIR/$tdir
3248         touch $DIR/$tdir/s
3249         touch $DIR/$tdir/exist
3250         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3251         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3252         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3253         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3254         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3255         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3256         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3257         return 0
3258 }
3259 run_test 31k "link to file: the same, non-existing, dir==============="
3260
3261 test_31m() {
3262         mkdir $DIR/d31m
3263         touch $DIR/d31m/s
3264         mkdir $DIR/d31m2
3265         touch $DIR/d31m2/exist
3266         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3267         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3268         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3269         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3270         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3271         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3272         return 0
3273 }
3274 run_test 31m "link to file: the same, non-existing, dir==============="
3275
3276 test_31n() {
3277         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3278         nlink=$(stat --format=%h $DIR/$tfile)
3279         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3280         local fd=$(free_fd)
3281         local cmd="exec $fd<$DIR/$tfile"
3282         eval $cmd
3283         cmd="exec $fd<&-"
3284         trap "eval $cmd" EXIT
3285         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3286         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3287         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3288         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3289         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3290         eval $cmd
3291 }
3292 run_test 31n "check link count of unlinked file"
3293
3294 link_one() {
3295         local tempfile=$(mktemp $1_XXXXXX)
3296         mlink $tempfile $1 2> /dev/null &&
3297                 echo "$BASHPID: link $tempfile to $1 succeeded"
3298         munlink $tempfile
3299 }
3300
3301 test_31o() { # LU-2901
3302         test_mkdir $DIR/$tdir
3303         for LOOP in $(seq 100); do
3304                 rm -f $DIR/$tdir/$tfile*
3305                 for THREAD in $(seq 8); do
3306                         link_one $DIR/$tdir/$tfile.$LOOP &
3307                 done
3308                 wait
3309                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3310                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3311                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3312                         break || true
3313         done
3314 }
3315 run_test 31o "duplicate hard links with same filename"
3316
3317 test_31p() {
3318         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3319
3320         test_mkdir $DIR/$tdir
3321         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3322         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3323
3324         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3325                 error "open unlink test1 failed"
3326         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3327                 error "open unlink test2 failed"
3328
3329         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3330                 error "test1 still exists"
3331         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3332                 error "test2 still exists"
3333 }
3334 run_test 31p "remove of open striped directory"
3335
3336 cleanup_test32_mount() {
3337         local rc=0
3338         trap 0
3339         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3340         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3341         losetup -d $loopdev || true
3342         rm -rf $DIR/$tdir
3343         return $rc
3344 }
3345
3346 test_32a() {
3347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3348
3349         echo "== more mountpoints and symlinks ================="
3350         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3351         trap cleanup_test32_mount EXIT
3352         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3353         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3354                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3355         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3356                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3357         cleanup_test32_mount
3358 }
3359 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3360
3361 test_32b() {
3362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3363
3364         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3365         trap cleanup_test32_mount EXIT
3366         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3367         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3368                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3369         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3370                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3371         cleanup_test32_mount
3372 }
3373 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3374
3375 test_32c() {
3376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3377
3378         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3379         trap cleanup_test32_mount EXIT
3380         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3381         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3382                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3383         test_mkdir -p $DIR/$tdir/d2/test_dir
3384         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3385                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3386         cleanup_test32_mount
3387 }
3388 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3389
3390 test_32d() {
3391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3392
3393         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3394         trap cleanup_test32_mount EXIT
3395         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3396         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3397                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3398         test_mkdir -p $DIR/$tdir/d2/test_dir
3399         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3400                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3401         cleanup_test32_mount
3402 }
3403 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3404
3405 test_32e() {
3406         rm -fr $DIR/$tdir
3407         test_mkdir -p $DIR/$tdir/tmp
3408         local tmp_dir=$DIR/$tdir/tmp
3409         ln -s $DIR/$tdir $tmp_dir/symlink11
3410         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3411         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3412         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3413 }
3414 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3415
3416 test_32f() {
3417         rm -fr $DIR/$tdir
3418         test_mkdir -p $DIR/$tdir/tmp
3419         local tmp_dir=$DIR/$tdir/tmp
3420         ln -s $DIR/$tdir $tmp_dir/symlink11
3421         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3422         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3423         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3424 }
3425 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3426
3427 test_32g() {
3428         local tmp_dir=$DIR/$tdir/tmp
3429         test_mkdir -p $tmp_dir
3430         test_mkdir $DIR/${tdir}2
3431         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3432         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3433         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3434         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3435         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3436         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3437 }
3438 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3439
3440 test_32h() {
3441         rm -fr $DIR/$tdir $DIR/${tdir}2
3442         tmp_dir=$DIR/$tdir/tmp
3443         test_mkdir -p $tmp_dir
3444         test_mkdir $DIR/${tdir}2
3445         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3446         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3447         ls $tmp_dir/symlink12 || error "listing symlink12"
3448         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3449 }
3450 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3451
3452 test_32i() {
3453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3454
3455         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3456         trap cleanup_test32_mount EXIT
3457         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3458         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3459                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3460         touch $DIR/$tdir/test_file
3461         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3462                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3463         cleanup_test32_mount
3464 }
3465 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3466
3467 test_32j() {
3468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3469
3470         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3471         trap cleanup_test32_mount EXIT
3472         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3473         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3474                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3475         touch $DIR/$tdir/test_file
3476         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3477                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3478         cleanup_test32_mount
3479 }
3480 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3481
3482 test_32k() {
3483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3484
3485         rm -fr $DIR/$tdir
3486         trap cleanup_test32_mount EXIT
3487         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3488         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3489                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3490         test_mkdir -p $DIR/$tdir/d2
3491         touch $DIR/$tdir/d2/test_file || error "touch failed"
3492         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3493                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3494         cleanup_test32_mount
3495 }
3496 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3497
3498 test_32l() {
3499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3500
3501         rm -fr $DIR/$tdir
3502         trap cleanup_test32_mount EXIT
3503         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3504         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3505                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3506         test_mkdir -p $DIR/$tdir/d2
3507         touch $DIR/$tdir/d2/test_file || error "touch failed"
3508         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3509                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3510         cleanup_test32_mount
3511 }
3512 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3513
3514 test_32m() {
3515         rm -fr $DIR/d32m
3516         test_mkdir -p $DIR/d32m/tmp
3517         TMP_DIR=$DIR/d32m/tmp
3518         ln -s $DIR $TMP_DIR/symlink11
3519         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3520         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3521                 error "symlink11 not a link"
3522         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3523                 error "symlink01 not a link"
3524 }
3525 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3526
3527 test_32n() {
3528         rm -fr $DIR/d32n
3529         test_mkdir -p $DIR/d32n/tmp
3530         TMP_DIR=$DIR/d32n/tmp
3531         ln -s $DIR $TMP_DIR/symlink11
3532         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3533         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3534         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3535 }
3536 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3537
3538 test_32o() {
3539         touch $DIR/$tfile
3540         test_mkdir -p $DIR/d32o/tmp
3541         TMP_DIR=$DIR/d32o/tmp
3542         ln -s $DIR/$tfile $TMP_DIR/symlink12
3543         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3544         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3545                 error "symlink12 not a link"
3546         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3547         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3548                 error "$DIR/d32o/tmp/symlink12 not file type"
3549         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3550                 error "$DIR/d32o/symlink02 not file type"
3551 }
3552 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3553
3554 test_32p() {
3555         log 32p_1
3556         rm -fr $DIR/d32p
3557         log 32p_2
3558         rm -f $DIR/$tfile
3559         log 32p_3
3560         touch $DIR/$tfile
3561         log 32p_4
3562         test_mkdir -p $DIR/d32p/tmp
3563         log 32p_5
3564         TMP_DIR=$DIR/d32p/tmp
3565         log 32p_6
3566         ln -s $DIR/$tfile $TMP_DIR/symlink12
3567         log 32p_7
3568         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3569         log 32p_8
3570         cat $DIR/d32p/tmp/symlink12 ||
3571                 error "Can't open $DIR/d32p/tmp/symlink12"
3572         log 32p_9
3573         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3574         log 32p_10
3575 }
3576 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3577
3578 test_32q() {
3579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3580
3581         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3582         trap cleanup_test32_mount EXIT
3583         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3584         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3585         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3586                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3587         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3588         cleanup_test32_mount
3589 }
3590 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3591
3592 test_32r() {
3593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3594
3595         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3596         trap cleanup_test32_mount EXIT
3597         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3598         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3599         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3600                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3601         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3602         cleanup_test32_mount
3603 }
3604 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3605
3606 test_33aa() {
3607         rm -f $DIR/$tfile
3608         touch $DIR/$tfile
3609         chmod 444 $DIR/$tfile
3610         chown $RUNAS_ID $DIR/$tfile
3611         log 33_1
3612         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3613         log 33_2
3614 }
3615 run_test 33aa "write file with mode 444 (should return error)"
3616
3617 test_33a() {
3618         rm -fr $DIR/$tdir
3619         test_mkdir $DIR/$tdir
3620         chown $RUNAS_ID $DIR/$tdir
3621         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3622                 error "$RUNAS create $tdir/$tfile failed"
3623         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3624                 error "open RDWR" || true
3625 }
3626 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3627
3628 test_33b() {
3629         rm -fr $DIR/$tdir
3630         test_mkdir $DIR/$tdir
3631         chown $RUNAS_ID $DIR/$tdir
3632         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3633 }
3634 run_test 33b "test open file with malformed flags (No panic)"
3635
3636 test_33c() {
3637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3638         remote_ost_nodsh && skip "remote OST with nodsh"
3639
3640         local ostnum
3641         local ostname
3642         local write_bytes
3643         local all_zeros
3644
3645         all_zeros=:
3646         rm -fr $DIR/$tdir
3647         test_mkdir $DIR/$tdir
3648         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3649
3650         sync
3651         for ostnum in $(seq $OSTCOUNT); do
3652                 # test-framework's OST numbering is one-based, while Lustre's
3653                 # is zero-based
3654                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3655                 # Parsing llobdstat's output sucks; we could grep the /proc
3656                 # path, but that's likely to not be as portable as using the
3657                 # llobdstat utility.  So we parse lctl output instead.
3658                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3659                         obdfilter/$ostname/stats |
3660                         awk '/^write_bytes/ {print $7}' )
3661                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3662                 if (( ${write_bytes:-0} > 0 ))
3663                 then
3664                         all_zeros=false
3665                         break;
3666                 fi
3667         done
3668
3669         $all_zeros || return 0
3670
3671         # Write four bytes
3672         echo foo > $DIR/$tdir/bar
3673         # Really write them
3674         sync
3675
3676         # Total up write_bytes after writing.  We'd better find non-zeros.
3677         for ostnum in $(seq $OSTCOUNT); do
3678                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3679                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3680                         obdfilter/$ostname/stats |
3681                         awk '/^write_bytes/ {print $7}' )
3682                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3683                 if (( ${write_bytes:-0} > 0 ))
3684                 then
3685                         all_zeros=false
3686                         break;
3687                 fi
3688         done
3689
3690         if $all_zeros
3691         then
3692                 for ostnum in $(seq $OSTCOUNT); do
3693                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3694                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3695                         do_facet ost$ostnum lctl get_param -n \
3696                                 obdfilter/$ostname/stats
3697                 done
3698                 error "OST not keeping write_bytes stats (b22312)"
3699         fi
3700 }
3701 run_test 33c "test llobdstat and write_bytes"
3702
3703 test_33d() {
3704         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3706
3707         local MDTIDX=1
3708         local remote_dir=$DIR/$tdir/remote_dir
3709
3710         test_mkdir $DIR/$tdir
3711         $LFS mkdir -i $MDTIDX $remote_dir ||
3712                 error "create remote directory failed"
3713
3714         touch $remote_dir/$tfile
3715         chmod 444 $remote_dir/$tfile
3716         chown $RUNAS_ID $remote_dir/$tfile
3717
3718         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3719
3720         chown $RUNAS_ID $remote_dir
3721         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3722                                         error "create" || true
3723         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3724                                     error "open RDWR" || true
3725         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3726 }
3727 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3728
3729 test_33e() {
3730         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3731
3732         mkdir $DIR/$tdir
3733
3734         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3735         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3736         mkdir $DIR/$tdir/local_dir
3737
3738         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3739         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3740         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3741
3742         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3743                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3744
3745         rmdir $DIR/$tdir/* || error "rmdir failed"
3746
3747         umask 777
3748         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3749         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3750         mkdir $DIR/$tdir/local_dir
3751
3752         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3753         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3754         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3755
3756         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3757                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3758
3759         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3760
3761         umask 000
3762         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3763         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3764         mkdir $DIR/$tdir/local_dir
3765
3766         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3767         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3768         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3769
3770         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3771                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3772 }
3773 run_test 33e "mkdir and striped directory should have same mode"
3774
3775 cleanup_33f() {
3776         trap 0
3777         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3778 }
3779
3780 test_33f() {
3781         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3782         remote_mds_nodsh && skip "remote MDS with nodsh"
3783
3784         mkdir $DIR/$tdir
3785         chmod go+rwx $DIR/$tdir
3786         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3787         trap cleanup_33f EXIT
3788
3789         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3790                 error "cannot create striped directory"
3791
3792         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3793                 error "cannot create files in striped directory"
3794
3795         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3796                 error "cannot remove files in striped directory"
3797
3798         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3799                 error "cannot remove striped directory"
3800
3801         cleanup_33f
3802 }
3803 run_test 33f "nonroot user can create, access, and remove a striped directory"
3804
3805 test_33g() {
3806         mkdir -p $DIR/$tdir/dir2
3807
3808         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3809         echo $err
3810         [[ $err =~ "exists" ]] || error "Not exists error"
3811 }
3812 run_test 33g "nonroot user create already existing root created file"
3813
3814 test_33h() {
3815         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3816         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
3817                 skip "Need MDS version at least 2.13.50"
3818
3819         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
3820                 error "mkdir $tdir failed"
3821         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
3822
3823         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
3824         local index2
3825
3826         for fname in $DIR/$tdir/$tfile.bak \
3827                      $DIR/$tdir/$tfile.SAV \
3828                      $DIR/$tdir/$tfile.orig \
3829                      $DIR/$tdir/$tfile~; do
3830                 touch $fname  || error "touch $fname failed"
3831                 index2=$($LFS getstripe -m $fname)
3832                 [ $index -eq $index2 ] ||
3833                         error "$fname MDT index mismatch $index != $index2"
3834         done
3835
3836         local failed=0
3837         for i in {1..50}; do
3838                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
3839                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
3840                         touch $fname  || error "touch $fname failed"
3841                         index2=$($LFS getstripe -m $fname)
3842                         if [[ $index != $index2 ]]; then
3843                                 failed=$((failed + 1))
3844                                 echo "$fname MDT index mismatch $index != $index2"
3845                         fi
3846                 done
3847         done
3848         echo "$failed MDT index mismatches"
3849         (( failed < 4 )) || error "MDT index mismatch $failed times"
3850
3851 }
3852 run_test 33h "temp file is located on the same MDT as target"
3853
3854 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3855 test_34a() {
3856         rm -f $DIR/f34
3857         $MCREATE $DIR/f34 || error "mcreate failed"
3858         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3859                 error "getstripe failed"
3860         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3861         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3862                 error "getstripe failed"
3863         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3864                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3865 }
3866 run_test 34a "truncate file that has not been opened ==========="
3867
3868 test_34b() {
3869         [ ! -f $DIR/f34 ] && test_34a
3870         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3871                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3872         $OPENFILE -f O_RDONLY $DIR/f34
3873         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3874                 error "getstripe failed"
3875         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3876                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3877 }
3878 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3879
3880 test_34c() {
3881         [ ! -f $DIR/f34 ] && test_34a
3882         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3883                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3884         $OPENFILE -f O_RDWR $DIR/f34
3885         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3886                 error "$LFS getstripe failed"
3887         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3888                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3889 }
3890 run_test 34c "O_RDWR opening file-with-size works =============="
3891
3892 test_34d() {
3893         [ ! -f $DIR/f34 ] && test_34a
3894         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3895                 error "dd failed"
3896         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3897                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3898         rm $DIR/f34
3899 }
3900 run_test 34d "write to sparse file ============================="
3901
3902 test_34e() {
3903         rm -f $DIR/f34e
3904         $MCREATE $DIR/f34e || error "mcreate failed"
3905         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3906         $CHECKSTAT -s 1000 $DIR/f34e ||
3907                 error "Size of $DIR/f34e not equal to 1000 bytes"
3908         $OPENFILE -f O_RDWR $DIR/f34e
3909         $CHECKSTAT -s 1000 $DIR/f34e ||
3910                 error "Size of $DIR/f34e not equal to 1000 bytes"
3911 }
3912 run_test 34e "create objects, some with size and some without =="
3913
3914 test_34f() { # bug 6242, 6243
3915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3916
3917         SIZE34F=48000
3918         rm -f $DIR/f34f
3919         $MCREATE $DIR/f34f || error "mcreate failed"
3920         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3921         dd if=$DIR/f34f of=$TMP/f34f
3922         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3923         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3924         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3925         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3926         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3927 }
3928 run_test 34f "read from a file with no objects until EOF ======="
3929
3930 test_34g() {
3931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3932
3933         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3934                 error "dd failed"
3935         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3936         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3937                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3938         cancel_lru_locks osc
3939         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3940                 error "wrong size after lock cancel"
3941
3942         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3943         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3944                 error "expanding truncate failed"
3945         cancel_lru_locks osc
3946         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3947                 error "wrong expanded size after lock cancel"
3948 }
3949 run_test 34g "truncate long file ==============================="
3950
3951 test_34h() {
3952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3953
3954         local gid=10
3955         local sz=1000
3956
3957         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3958         sync # Flush the cache so that multiop below does not block on cache
3959              # flush when getting the group lock
3960         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3961         MULTIPID=$!
3962
3963         # Since just timed wait is not good enough, let's do a sync write
3964         # that way we are sure enough time for a roundtrip + processing
3965         # passed + 2 seconds of extra margin.
3966         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3967         rm $DIR/${tfile}-1
3968         sleep 2
3969
3970         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3971                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3972                 kill -9 $MULTIPID
3973         fi
3974         wait $MULTIPID
3975         local nsz=`stat -c %s $DIR/$tfile`
3976         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3977 }
3978 run_test 34h "ftruncate file under grouplock should not block"
3979
3980 test_35a() {
3981         cp /bin/sh $DIR/f35a
3982         chmod 444 $DIR/f35a
3983         chown $RUNAS_ID $DIR/f35a
3984         $RUNAS $DIR/f35a && error || true
3985         rm $DIR/f35a
3986 }
3987 run_test 35a "exec file with mode 444 (should return and not leak)"
3988
3989 test_36a() {
3990         rm -f $DIR/f36
3991         utime $DIR/f36 || error "utime failed for MDS"
3992 }
3993 run_test 36a "MDS utime check (mknod, utime)"
3994
3995 test_36b() {
3996         echo "" > $DIR/f36
3997         utime $DIR/f36 || error "utime failed for OST"
3998 }
3999 run_test 36b "OST utime check (open, utime)"
4000
4001 test_36c() {
4002         rm -f $DIR/d36/f36
4003         test_mkdir $DIR/d36
4004         chown $RUNAS_ID $DIR/d36
4005         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4006 }
4007 run_test 36c "non-root MDS utime check (mknod, utime)"
4008
4009 test_36d() {
4010         [ ! -d $DIR/d36 ] && test_36c
4011         echo "" > $DIR/d36/f36
4012         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4013 }
4014 run_test 36d "non-root OST utime check (open, utime)"
4015
4016 test_36e() {
4017         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4018
4019         test_mkdir $DIR/$tdir
4020         touch $DIR/$tdir/$tfile
4021         $RUNAS utime $DIR/$tdir/$tfile &&
4022                 error "utime worked, expected failure" || true
4023 }
4024 run_test 36e "utime on non-owned file (should return error)"
4025
4026 subr_36fh() {
4027         local fl="$1"
4028         local LANG_SAVE=$LANG
4029         local LC_LANG_SAVE=$LC_LANG
4030         export LANG=C LC_LANG=C # for date language
4031
4032         DATESTR="Dec 20  2000"
4033         test_mkdir $DIR/$tdir
4034         lctl set_param fail_loc=$fl
4035         date; date +%s
4036         cp /etc/hosts $DIR/$tdir/$tfile
4037         sync & # write RPC generated with "current" inode timestamp, but delayed
4038         sleep 1
4039         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4040         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4041         cancel_lru_locks $OSC
4042         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4043         date; date +%s
4044         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4045                 echo "BEFORE: $LS_BEFORE" && \
4046                 echo "AFTER : $LS_AFTER" && \
4047                 echo "WANT  : $DATESTR" && \
4048                 error "$DIR/$tdir/$tfile timestamps changed" || true
4049
4050         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4051 }
4052
4053 test_36f() {
4054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4055
4056         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4057         subr_36fh "0x80000214"
4058 }
4059 run_test 36f "utime on file racing with OST BRW write =========="
4060
4061 test_36g() {
4062         remote_ost_nodsh && skip "remote OST with nodsh"
4063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4064         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4065                 skip "Need MDS version at least 2.12.51"
4066
4067         local fmd_max_age
4068         local fmd
4069         local facet="ost1"
4070         local tgt="obdfilter"
4071
4072         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4073
4074         test_mkdir $DIR/$tdir
4075         fmd_max_age=$(do_facet $facet \
4076                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4077                 head -n 1")
4078
4079         echo "FMD max age: ${fmd_max_age}s"
4080         touch $DIR/$tdir/$tfile
4081         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4082                 gawk '{cnt=cnt+$1}  END{print cnt}')
4083         echo "FMD before: $fmd"
4084         [[ $fmd == 0 ]] &&
4085                 error "FMD wasn't create by touch"
4086         sleep $((fmd_max_age + 12))
4087         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4088                 gawk '{cnt=cnt+$1}  END{print cnt}')
4089         echo "FMD after: $fmd"
4090         [[ $fmd == 0 ]] ||
4091                 error "FMD wasn't expired by ping"
4092 }
4093 run_test 36g "FMD cache expiry ====================="
4094
4095 test_36h() {
4096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4097
4098         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4099         subr_36fh "0x80000227"
4100 }
4101 run_test 36h "utime on file racing with OST BRW write =========="
4102
4103 test_36i() {
4104         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4105
4106         test_mkdir $DIR/$tdir
4107         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4108
4109         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4110         local new_mtime=$((mtime + 200))
4111
4112         #change Modify time of striped dir
4113         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4114                         error "change mtime failed"
4115
4116         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4117
4118         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4119 }
4120 run_test 36i "change mtime on striped directory"
4121
4122 # test_37 - duplicate with tests 32q 32r
4123
4124 test_38() {
4125         local file=$DIR/$tfile
4126         touch $file
4127         openfile -f O_DIRECTORY $file
4128         local RC=$?
4129         local ENOTDIR=20
4130         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4131         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4132 }
4133 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4134
4135 test_39a() { # was test_39
4136         touch $DIR/$tfile
4137         touch $DIR/${tfile}2
4138 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4139 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4140 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4141         sleep 2
4142         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4143         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4144                 echo "mtime"
4145                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4146                 echo "atime"
4147                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4148                 echo "ctime"
4149                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4150                 error "O_TRUNC didn't change timestamps"
4151         fi
4152 }
4153 run_test 39a "mtime changed on create"
4154
4155 test_39b() {
4156         test_mkdir -c1 $DIR/$tdir
4157         cp -p /etc/passwd $DIR/$tdir/fopen
4158         cp -p /etc/passwd $DIR/$tdir/flink
4159         cp -p /etc/passwd $DIR/$tdir/funlink
4160         cp -p /etc/passwd $DIR/$tdir/frename
4161         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4162
4163         sleep 1
4164         echo "aaaaaa" >> $DIR/$tdir/fopen
4165         echo "aaaaaa" >> $DIR/$tdir/flink
4166         echo "aaaaaa" >> $DIR/$tdir/funlink
4167         echo "aaaaaa" >> $DIR/$tdir/frename
4168
4169         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4170         local link_new=`stat -c %Y $DIR/$tdir/flink`
4171         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4172         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4173
4174         cat $DIR/$tdir/fopen > /dev/null
4175         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4176         rm -f $DIR/$tdir/funlink2
4177         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4178
4179         for (( i=0; i < 2; i++ )) ; do
4180                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4181                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4182                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4183                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4184
4185                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4186                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4187                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4188                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4189
4190                 cancel_lru_locks $OSC
4191                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4192         done
4193 }
4194 run_test 39b "mtime change on open, link, unlink, rename  ======"
4195
4196 # this should be set to past
4197 TEST_39_MTIME=`date -d "1 year ago" +%s`
4198
4199 # bug 11063
4200 test_39c() {
4201         touch $DIR1/$tfile
4202         sleep 2
4203         local mtime0=`stat -c %Y $DIR1/$tfile`
4204
4205         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4206         local mtime1=`stat -c %Y $DIR1/$tfile`
4207         [ "$mtime1" = $TEST_39_MTIME ] || \
4208                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4209
4210         local d1=`date +%s`
4211         echo hello >> $DIR1/$tfile
4212         local d2=`date +%s`
4213         local mtime2=`stat -c %Y $DIR1/$tfile`
4214         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4215                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4216
4217         mv $DIR1/$tfile $DIR1/$tfile-1
4218
4219         for (( i=0; i < 2; i++ )) ; do
4220                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4221                 [ "$mtime2" = "$mtime3" ] || \
4222                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4223
4224                 cancel_lru_locks $OSC
4225                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4226         done
4227 }
4228 run_test 39c "mtime change on rename ==========================="
4229
4230 # bug 21114
4231 test_39d() {
4232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4233
4234         touch $DIR1/$tfile
4235         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4236
4237         for (( i=0; i < 2; i++ )) ; do
4238                 local mtime=`stat -c %Y $DIR1/$tfile`
4239                 [ $mtime = $TEST_39_MTIME ] || \
4240                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4241
4242                 cancel_lru_locks $OSC
4243                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4244         done
4245 }
4246 run_test 39d "create, utime, stat =============================="
4247
4248 # bug 21114
4249 test_39e() {
4250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4251
4252         touch $DIR1/$tfile
4253         local mtime1=`stat -c %Y $DIR1/$tfile`
4254
4255         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4256
4257         for (( i=0; i < 2; i++ )) ; do
4258                 local mtime2=`stat -c %Y $DIR1/$tfile`
4259                 [ $mtime2 = $TEST_39_MTIME ] || \
4260                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4261
4262                 cancel_lru_locks $OSC
4263                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4264         done
4265 }
4266 run_test 39e "create, stat, utime, stat ========================"
4267
4268 # bug 21114
4269 test_39f() {
4270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4271
4272         touch $DIR1/$tfile
4273         mtime1=`stat -c %Y $DIR1/$tfile`
4274
4275         sleep 2
4276         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4277
4278         for (( i=0; i < 2; i++ )) ; do
4279                 local mtime2=`stat -c %Y $DIR1/$tfile`
4280                 [ $mtime2 = $TEST_39_MTIME ] || \
4281                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4282
4283                 cancel_lru_locks $OSC
4284                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4285         done
4286 }
4287 run_test 39f "create, stat, sleep, utime, stat ================="
4288
4289 # bug 11063
4290 test_39g() {
4291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4292
4293         echo hello >> $DIR1/$tfile
4294         local mtime1=`stat -c %Y $DIR1/$tfile`
4295
4296         sleep 2
4297         chmod o+r $DIR1/$tfile
4298
4299         for (( i=0; i < 2; i++ )) ; do
4300                 local mtime2=`stat -c %Y $DIR1/$tfile`
4301                 [ "$mtime1" = "$mtime2" ] || \
4302                         error "lost mtime: $mtime2, should be $mtime1"
4303
4304                 cancel_lru_locks $OSC
4305                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4306         done
4307 }
4308 run_test 39g "write, chmod, stat ==============================="
4309
4310 # bug 11063
4311 test_39h() {
4312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4313
4314         touch $DIR1/$tfile
4315         sleep 1
4316
4317         local d1=`date`
4318         echo hello >> $DIR1/$tfile
4319         local mtime1=`stat -c %Y $DIR1/$tfile`
4320
4321         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4322         local d2=`date`
4323         if [ "$d1" != "$d2" ]; then
4324                 echo "write and touch not within one second"
4325         else
4326                 for (( i=0; i < 2; i++ )) ; do
4327                         local mtime2=`stat -c %Y $DIR1/$tfile`
4328                         [ "$mtime2" = $TEST_39_MTIME ] || \
4329                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4330
4331                         cancel_lru_locks $OSC
4332                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4333                 done
4334         fi
4335 }
4336 run_test 39h "write, utime within one second, stat ============="
4337
4338 test_39i() {
4339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4340
4341         touch $DIR1/$tfile
4342         sleep 1
4343
4344         echo hello >> $DIR1/$tfile
4345         local mtime1=`stat -c %Y $DIR1/$tfile`
4346
4347         mv $DIR1/$tfile $DIR1/$tfile-1
4348
4349         for (( i=0; i < 2; i++ )) ; do
4350                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4351
4352                 [ "$mtime1" = "$mtime2" ] || \
4353                         error "lost mtime: $mtime2, should be $mtime1"
4354
4355                 cancel_lru_locks $OSC
4356                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4357         done
4358 }
4359 run_test 39i "write, rename, stat =============================="
4360
4361 test_39j() {
4362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4363
4364         start_full_debug_logging
4365         touch $DIR1/$tfile
4366         sleep 1
4367
4368         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4369         lctl set_param fail_loc=0x80000412
4370         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4371                 error "multiop failed"
4372         local multipid=$!
4373         local mtime1=`stat -c %Y $DIR1/$tfile`
4374
4375         mv $DIR1/$tfile $DIR1/$tfile-1
4376
4377         kill -USR1 $multipid
4378         wait $multipid || error "multiop close failed"
4379
4380         for (( i=0; i < 2; i++ )) ; do
4381                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4382                 [ "$mtime1" = "$mtime2" ] ||
4383                         error "mtime is lost on close: $mtime2, " \
4384                               "should be $mtime1"
4385
4386                 cancel_lru_locks
4387                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4388         done
4389         lctl set_param fail_loc=0
4390         stop_full_debug_logging
4391 }
4392 run_test 39j "write, rename, close, stat ======================="
4393
4394 test_39k() {
4395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4396
4397         touch $DIR1/$tfile
4398         sleep 1
4399
4400         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4401         local multipid=$!
4402         local mtime1=`stat -c %Y $DIR1/$tfile`
4403
4404         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4405
4406         kill -USR1 $multipid
4407         wait $multipid || error "multiop close failed"
4408
4409         for (( i=0; i < 2; i++ )) ; do
4410                 local mtime2=`stat -c %Y $DIR1/$tfile`
4411
4412                 [ "$mtime2" = $TEST_39_MTIME ] || \
4413                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4414
4415                 cancel_lru_locks
4416                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4417         done
4418 }
4419 run_test 39k "write, utime, close, stat ========================"
4420
4421 # this should be set to future
4422 TEST_39_ATIME=`date -d "1 year" +%s`
4423
4424 test_39l() {
4425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4426         remote_mds_nodsh && skip "remote MDS with nodsh"
4427
4428         local atime_diff=$(do_facet $SINGLEMDS \
4429                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4430         rm -rf $DIR/$tdir
4431         mkdir -p $DIR/$tdir
4432
4433         # test setting directory atime to future
4434         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4435         local atime=$(stat -c %X $DIR/$tdir)
4436         [ "$atime" = $TEST_39_ATIME ] ||
4437                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4438
4439         # test setting directory atime from future to now
4440         local now=$(date +%s)
4441         touch -a -d @$now $DIR/$tdir
4442
4443         atime=$(stat -c %X $DIR/$tdir)
4444         [ "$atime" -eq "$now"  ] ||
4445                 error "atime is not updated from future: $atime, $now"
4446
4447         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4448         sleep 3
4449
4450         # test setting directory atime when now > dir atime + atime_diff
4451         local d1=$(date +%s)
4452         ls $DIR/$tdir
4453         local d2=$(date +%s)
4454         cancel_lru_locks mdc
4455         atime=$(stat -c %X $DIR/$tdir)
4456         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4457                 error "atime is not updated  : $atime, should be $d2"
4458
4459         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4460         sleep 3
4461
4462         # test not setting directory atime when now < dir atime + atime_diff
4463         ls $DIR/$tdir
4464         cancel_lru_locks mdc
4465         atime=$(stat -c %X $DIR/$tdir)
4466         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4467                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4468
4469         do_facet $SINGLEMDS \
4470                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4471 }
4472 run_test 39l "directory atime update ==========================="
4473
4474 test_39m() {
4475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4476
4477         touch $DIR1/$tfile
4478         sleep 2
4479         local far_past_mtime=$(date -d "May 29 1953" +%s)
4480         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4481
4482         touch -m -d @$far_past_mtime $DIR1/$tfile
4483         touch -a -d @$far_past_atime $DIR1/$tfile
4484
4485         for (( i=0; i < 2; i++ )) ; do
4486                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4487                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4488                         error "atime or mtime set incorrectly"
4489
4490                 cancel_lru_locks $OSC
4491                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4492         done
4493 }
4494 run_test 39m "test atime and mtime before 1970"
4495
4496 test_39n() { # LU-3832
4497         remote_mds_nodsh && skip "remote MDS with nodsh"
4498
4499         local atime_diff=$(do_facet $SINGLEMDS \
4500                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4501         local atime0
4502         local atime1
4503         local atime2
4504
4505         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4506
4507         rm -rf $DIR/$tfile
4508         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4509         atime0=$(stat -c %X $DIR/$tfile)
4510
4511         sleep 5
4512         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4513         atime1=$(stat -c %X $DIR/$tfile)
4514
4515         sleep 5
4516         cancel_lru_locks mdc
4517         cancel_lru_locks osc
4518         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4519         atime2=$(stat -c %X $DIR/$tfile)
4520
4521         do_facet $SINGLEMDS \
4522                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4523
4524         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4525         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4526 }
4527 run_test 39n "check that O_NOATIME is honored"
4528
4529 test_39o() {
4530         TESTDIR=$DIR/$tdir/$tfile
4531         [ -e $TESTDIR ] && rm -rf $TESTDIR
4532         mkdir -p $TESTDIR
4533         cd $TESTDIR
4534         links1=2
4535         ls
4536         mkdir a b
4537         ls
4538         links2=$(stat -c %h .)
4539         [ $(($links1 + 2)) != $links2 ] &&
4540                 error "wrong links count $(($links1 + 2)) != $links2"
4541         rmdir b
4542         links3=$(stat -c %h .)
4543         [ $(($links1 + 1)) != $links3 ] &&
4544                 error "wrong links count $links1 != $links3"
4545         return 0
4546 }
4547 run_test 39o "directory cached attributes updated after create"
4548
4549 test_39p() {
4550         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4551
4552         local MDTIDX=1
4553         TESTDIR=$DIR/$tdir/$tdir
4554         [ -e $TESTDIR ] && rm -rf $TESTDIR
4555         test_mkdir -p $TESTDIR
4556         cd $TESTDIR
4557         links1=2
4558         ls
4559         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4560         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4561         ls
4562         links2=$(stat -c %h .)
4563         [ $(($links1 + 2)) != $links2 ] &&
4564                 error "wrong links count $(($links1 + 2)) != $links2"
4565         rmdir remote_dir2
4566         links3=$(stat -c %h .)
4567         [ $(($links1 + 1)) != $links3 ] &&
4568                 error "wrong links count $links1 != $links3"
4569         return 0
4570 }
4571 run_test 39p "remote directory cached attributes updated after create ========"
4572
4573 test_39r() {
4574         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4575                 skip "no atime update on old OST"
4576         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4577                 skip_env "ldiskfs only test"
4578         fi
4579
4580         local saved_adiff
4581         saved_adiff=$(do_facet ost1 \
4582                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4583         stack_trap "do_facet ost1 \
4584                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4585
4586         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4587
4588         $LFS setstripe -i 0 $DIR/$tfile
4589         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4590                 error "can't write initial file"
4591         cancel_lru_locks osc
4592
4593         # exceed atime_diff and access file
4594         sleep 6
4595         dd if=$DIR/$tfile of=/dev/null || error "can't udpate atime"
4596
4597         local atime_cli=$(stat -c %X $DIR/$tfile)
4598         echo "client atime: $atime_cli"
4599         # allow atime update to be written to device
4600         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4601         sleep 5
4602
4603         local ostdev=$(ostdevname 1)
4604         local fid=($(lfs getstripe -y $DIR/$tfile |
4605                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4606         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4607         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4608
4609         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4610         local atime_ost=$(do_facet ost1 "$cmd" |&
4611                           awk -F'[: ]' '/atime:/ { print $4 }')
4612         (( atime_cli == atime_ost )) ||
4613                 error "atime on client $atime_cli != ost $atime_ost"
4614 }
4615 run_test 39r "lazy atime update on OST"
4616
4617 test_39q() { # LU-8041
4618         local testdir=$DIR/$tdir
4619         mkdir -p $testdir
4620         multiop_bg_pause $testdir D_c || error "multiop failed"
4621         local multipid=$!
4622         cancel_lru_locks mdc
4623         kill -USR1 $multipid
4624         local atime=$(stat -c %X $testdir)
4625         [ "$atime" -ne 0 ] || error "atime is zero"
4626 }
4627 run_test 39q "close won't zero out atime"
4628
4629 test_40() {
4630         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4631         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4632                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4633         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4634                 error "$tfile is not 4096 bytes in size"
4635 }
4636 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4637
4638 test_41() {
4639         # bug 1553
4640         small_write $DIR/f41 18
4641 }
4642 run_test 41 "test small file write + fstat ====================="
4643
4644 count_ost_writes() {
4645         lctl get_param -n ${OSC}.*.stats |
4646                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4647                         END { printf("%0.0f", writes) }'
4648 }
4649
4650 # decent default
4651 WRITEBACK_SAVE=500
4652 DIRTY_RATIO_SAVE=40
4653 MAX_DIRTY_RATIO=50
4654 BG_DIRTY_RATIO_SAVE=10
4655 MAX_BG_DIRTY_RATIO=25
4656
4657 start_writeback() {
4658         trap 0
4659         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4660         # dirty_ratio, dirty_background_ratio
4661         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4662                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4663                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4664                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4665         else
4666                 # if file not here, we are a 2.4 kernel
4667                 kill -CONT `pidof kupdated`
4668         fi
4669 }
4670
4671 stop_writeback() {
4672         # setup the trap first, so someone cannot exit the test at the
4673         # exact wrong time and mess up a machine
4674         trap start_writeback EXIT
4675         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4676         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4677                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4678                 sysctl -w vm.dirty_writeback_centisecs=0
4679                 sysctl -w vm.dirty_writeback_centisecs=0
4680                 # save and increase /proc/sys/vm/dirty_ratio
4681                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4682                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4683                 # save and increase /proc/sys/vm/dirty_background_ratio
4684                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4685                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4686         else
4687                 # if file not here, we are a 2.4 kernel
4688                 kill -STOP `pidof kupdated`
4689         fi
4690 }
4691
4692 # ensure that all stripes have some grant before we test client-side cache
4693 setup_test42() {
4694         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4695                 dd if=/dev/zero of=$i bs=4k count=1
4696                 rm $i
4697         done
4698 }
4699
4700 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4701 # file truncation, and file removal.
4702 test_42a() {
4703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4704
4705         setup_test42
4706         cancel_lru_locks $OSC
4707         stop_writeback
4708         sync; sleep 1; sync # just to be safe
4709         BEFOREWRITES=`count_ost_writes`
4710         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4711         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4712         AFTERWRITES=`count_ost_writes`
4713         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4714                 error "$BEFOREWRITES < $AFTERWRITES"
4715         start_writeback
4716 }
4717 run_test 42a "ensure that we don't flush on close"
4718
4719 test_42b() {
4720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4721
4722         setup_test42
4723         cancel_lru_locks $OSC
4724         stop_writeback
4725         sync
4726         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4727         BEFOREWRITES=$(count_ost_writes)
4728         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4729         AFTERWRITES=$(count_ost_writes)
4730         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4731                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4732         fi
4733         BEFOREWRITES=$(count_ost_writes)
4734         sync || error "sync: $?"
4735         AFTERWRITES=$(count_ost_writes)
4736         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4737                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4738         fi
4739         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4740         start_writeback
4741         return 0
4742 }
4743 run_test 42b "test destroy of file with cached dirty data ======"
4744
4745 # if these tests just want to test the effect of truncation,
4746 # they have to be very careful.  consider:
4747 # - the first open gets a {0,EOF}PR lock
4748 # - the first write conflicts and gets a {0, count-1}PW
4749 # - the rest of the writes are under {count,EOF}PW
4750 # - the open for truncate tries to match a {0,EOF}PR
4751 #   for the filesize and cancels the PWs.
4752 # any number of fixes (don't get {0,EOF} on open, match
4753 # composite locks, do smarter file size management) fix
4754 # this, but for now we want these tests to verify that
4755 # the cancellation with truncate intent works, so we
4756 # start the file with a full-file pw lock to match against
4757 # until the truncate.
4758 trunc_test() {
4759         test=$1
4760         file=$DIR/$test
4761         offset=$2
4762         cancel_lru_locks $OSC
4763         stop_writeback
4764         # prime the file with 0,EOF PW to match
4765         touch $file
4766         $TRUNCATE $file 0
4767         sync; sync
4768         # now the real test..
4769         dd if=/dev/zero of=$file bs=1024 count=100
4770         BEFOREWRITES=`count_ost_writes`
4771         $TRUNCATE $file $offset
4772         cancel_lru_locks $OSC
4773         AFTERWRITES=`count_ost_writes`
4774         start_writeback
4775 }
4776
4777 test_42c() {
4778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4779
4780         trunc_test 42c 1024
4781         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4782                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4783         rm $file
4784 }
4785 run_test 42c "test partial truncate of file with cached dirty data"
4786
4787 test_42d() {
4788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4789
4790         trunc_test 42d 0
4791         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4792                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4793         rm $file
4794 }
4795 run_test 42d "test complete truncate of file with cached dirty data"
4796
4797 test_42e() { # bug22074
4798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4799
4800         local TDIR=$DIR/${tdir}e
4801         local pages=16 # hardcoded 16 pages, don't change it.
4802         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4803         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4804         local max_dirty_mb
4805         local warmup_files
4806
4807         test_mkdir $DIR/${tdir}e
4808         $LFS setstripe -c 1 $TDIR
4809         createmany -o $TDIR/f $files
4810
4811         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4812
4813         # we assume that with $OSTCOUNT files, at least one of them will
4814         # be allocated on OST0.
4815         warmup_files=$((OSTCOUNT * max_dirty_mb))
4816         createmany -o $TDIR/w $warmup_files
4817
4818         # write a large amount of data into one file and sync, to get good
4819         # avail_grant number from OST.
4820         for ((i=0; i<$warmup_files; i++)); do
4821                 idx=$($LFS getstripe -i $TDIR/w$i)
4822                 [ $idx -ne 0 ] && continue
4823                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4824                 break
4825         done
4826         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4827         sync
4828         $LCTL get_param $proc_osc0/cur_dirty_bytes
4829         $LCTL get_param $proc_osc0/cur_grant_bytes
4830
4831         # create as much dirty pages as we can while not to trigger the actual
4832         # RPCs directly. but depends on the env, VFS may trigger flush during this
4833         # period, hopefully we are good.
4834         for ((i=0; i<$warmup_files; i++)); do
4835                 idx=$($LFS getstripe -i $TDIR/w$i)
4836                 [ $idx -ne 0 ] && continue
4837                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4838         done
4839         $LCTL get_param $proc_osc0/cur_dirty_bytes
4840         $LCTL get_param $proc_osc0/cur_grant_bytes
4841
4842         # perform the real test
4843         $LCTL set_param $proc_osc0/rpc_stats 0
4844         for ((;i<$files; i++)); do
4845                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4846                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4847         done
4848         sync
4849         $LCTL get_param $proc_osc0/rpc_stats
4850
4851         local percent=0
4852         local have_ppr=false
4853         $LCTL get_param $proc_osc0/rpc_stats |
4854                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4855                         # skip lines until we are at the RPC histogram data
4856                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4857                         $have_ppr || continue
4858
4859                         # we only want the percent stat for < 16 pages
4860                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4861
4862                         percent=$((percent + WPCT))
4863                         if [[ $percent -gt 15 ]]; then
4864                                 error "less than 16-pages write RPCs" \
4865                                       "$percent% > 15%"
4866                                 break
4867                         fi
4868                 done
4869         rm -rf $TDIR
4870 }
4871 run_test 42e "verify sub-RPC writes are not done synchronously"
4872
4873 test_43A() { # was test_43
4874         test_mkdir $DIR/$tdir
4875         cp -p /bin/ls $DIR/$tdir/$tfile
4876         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4877         pid=$!
4878         # give multiop a chance to open
4879         sleep 1
4880
4881         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4882         kill -USR1 $pid
4883 }
4884 run_test 43A "execution of file opened for write should return -ETXTBSY"
4885
4886 test_43a() {
4887         test_mkdir $DIR/$tdir
4888         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4889         $DIR/$tdir/sleep 60 &
4890         SLEEP_PID=$!
4891         # Make sure exec of $tdir/sleep wins race with truncate
4892         sleep 1
4893         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4894         kill $SLEEP_PID
4895 }
4896 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4897
4898 test_43b() {
4899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4900
4901         test_mkdir $DIR/$tdir
4902         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4903         $DIR/$tdir/sleep 60 &
4904         SLEEP_PID=$!
4905         # Make sure exec of $tdir/sleep wins race with truncate
4906         sleep 1
4907         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4908         kill $SLEEP_PID
4909 }
4910 run_test 43b "truncate of file being executed should return -ETXTBSY"
4911
4912 test_43c() {
4913         local testdir="$DIR/$tdir"
4914         test_mkdir $testdir
4915         cp $SHELL $testdir/
4916         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4917                 ( cd $testdir && md5sum -c )
4918 }
4919 run_test 43c "md5sum of copy into lustre"
4920
4921 test_44A() { # was test_44
4922         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4923
4924         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4925         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4926 }
4927 run_test 44A "zero length read from a sparse stripe"
4928
4929 test_44a() {
4930         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4931                 awk '{ print $2 }')
4932         [ -z "$nstripe" ] && skip "can't get stripe info"
4933         [[ $nstripe -gt $OSTCOUNT ]] &&
4934                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4935
4936         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4937                 awk '{ print $2 }')
4938         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4939                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4940                         awk '{ print $2 }')
4941         fi
4942
4943         OFFSETS="0 $((stride/2)) $((stride-1))"
4944         for offset in $OFFSETS; do
4945                 for i in $(seq 0 $((nstripe-1))); do
4946                         local GLOBALOFFSETS=""
4947                         # size in Bytes
4948                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4949                         local myfn=$DIR/d44a-$size
4950                         echo "--------writing $myfn at $size"
4951                         ll_sparseness_write $myfn $size ||
4952                                 error "ll_sparseness_write"
4953                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4954                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4955                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4956
4957                         for j in $(seq 0 $((nstripe-1))); do
4958                                 # size in Bytes
4959                                 size=$((((j + $nstripe )*$stride + $offset)))
4960                                 ll_sparseness_write $myfn $size ||
4961                                         error "ll_sparseness_write"
4962                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4963                         done
4964                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4965                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4966                         rm -f $myfn
4967                 done
4968         done
4969 }
4970 run_test 44a "test sparse pwrite ==============================="
4971
4972 dirty_osc_total() {
4973         tot=0
4974         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4975                 tot=$(($tot + $d))
4976         done
4977         echo $tot
4978 }
4979 do_dirty_record() {
4980         before=`dirty_osc_total`
4981         echo executing "\"$*\""
4982         eval $*
4983         after=`dirty_osc_total`
4984         echo before $before, after $after
4985 }
4986 test_45() {
4987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4988
4989         f="$DIR/f45"
4990         # Obtain grants from OST if it supports it
4991         echo blah > ${f}_grant
4992         stop_writeback
4993         sync
4994         do_dirty_record "echo blah > $f"
4995         [[ $before -eq $after ]] && error "write wasn't cached"
4996         do_dirty_record "> $f"
4997         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4998         do_dirty_record "echo blah > $f"
4999         [[ $before -eq $after ]] && error "write wasn't cached"
5000         do_dirty_record "sync"
5001         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5002         do_dirty_record "echo blah > $f"
5003         [[ $before -eq $after ]] && error "write wasn't cached"
5004         do_dirty_record "cancel_lru_locks osc"
5005         [[ $before -gt $after ]] ||
5006                 error "lock cancellation didn't lower dirty count"
5007         start_writeback
5008 }
5009 run_test 45 "osc io page accounting ============================"
5010
5011 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5012 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5013 # objects offset and an assert hit when an rpc was built with 1023's mapped
5014 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5015 test_46() {
5016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5017
5018         f="$DIR/f46"
5019         stop_writeback
5020         sync
5021         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5022         sync
5023         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5024         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5025         sync
5026         start_writeback
5027 }
5028 run_test 46 "dirtying a previously written page ================"
5029
5030 # test_47 is removed "Device nodes check" is moved to test_28
5031
5032 test_48a() { # bug 2399
5033         [ "$mds1_FSTYPE" = "zfs" ] &&
5034         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5035                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5036
5037         test_mkdir $DIR/$tdir
5038         cd $DIR/$tdir
5039         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5040         test_mkdir $DIR/$tdir
5041         touch foo || error "'touch foo' failed after recreating cwd"
5042         test_mkdir bar
5043         touch .foo || error "'touch .foo' failed after recreating cwd"
5044         test_mkdir .bar
5045         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5046         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5047         cd . || error "'cd .' failed after recreating cwd"
5048         mkdir . && error "'mkdir .' worked after recreating cwd"
5049         rmdir . && error "'rmdir .' worked after recreating cwd"
5050         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5051         cd .. || error "'cd ..' failed after recreating cwd"
5052 }
5053 run_test 48a "Access renamed working dir (should return errors)="
5054
5055 test_48b() { # bug 2399
5056         rm -rf $DIR/$tdir
5057         test_mkdir $DIR/$tdir
5058         cd $DIR/$tdir
5059         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5060         touch foo && error "'touch foo' worked after removing cwd"
5061         mkdir foo && error "'mkdir foo' worked after removing cwd"
5062         touch .foo && error "'touch .foo' worked after removing cwd"
5063         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5064         ls . > /dev/null && error "'ls .' worked after removing cwd"
5065         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5066         mkdir . && error "'mkdir .' worked after removing cwd"
5067         rmdir . && error "'rmdir .' worked after removing cwd"
5068         ln -s . foo && error "'ln -s .' worked after removing cwd"
5069         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5070 }
5071 run_test 48b "Access removed working dir (should return errors)="
5072
5073 test_48c() { # bug 2350
5074         #lctl set_param debug=-1
5075         #set -vx
5076         rm -rf $DIR/$tdir
5077         test_mkdir -p $DIR/$tdir/dir
5078         cd $DIR/$tdir/dir
5079         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5080         $TRACE touch foo && error "touch foo worked after removing cwd"
5081         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5082         touch .foo && error "touch .foo worked after removing cwd"
5083         mkdir .foo && error "mkdir .foo worked after removing cwd"
5084         $TRACE ls . && error "'ls .' worked after removing cwd"
5085         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5086         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5087         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5088         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5089         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5090 }
5091 run_test 48c "Access removed working subdir (should return errors)"
5092
5093 test_48d() { # bug 2350
5094         #lctl set_param debug=-1
5095         #set -vx
5096         rm -rf $DIR/$tdir
5097         test_mkdir -p $DIR/$tdir/dir
5098         cd $DIR/$tdir/dir
5099         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5100         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5101         $TRACE touch foo && error "'touch foo' worked after removing parent"
5102         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5103         touch .foo && error "'touch .foo' worked after removing parent"
5104         mkdir .foo && error "mkdir .foo worked after removing parent"
5105         $TRACE ls . && error "'ls .' worked after removing parent"
5106         $TRACE ls .. && error "'ls ..' worked after removing parent"
5107         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5108         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5109         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5110         true
5111 }
5112 run_test 48d "Access removed parent subdir (should return errors)"
5113
5114 test_48e() { # bug 4134
5115         #lctl set_param debug=-1
5116         #set -vx
5117         rm -rf $DIR/$tdir
5118         test_mkdir -p $DIR/$tdir/dir
5119         cd $DIR/$tdir/dir
5120         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5121         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5122         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5123         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5124         # On a buggy kernel addition of "touch foo" after cd .. will
5125         # produce kernel oops in lookup_hash_it
5126         touch ../foo && error "'cd ..' worked after recreate parent"
5127         cd $DIR
5128         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5129 }
5130 run_test 48e "Access to recreated parent subdir (should return errors)"
5131
5132 test_49() { # LU-1030
5133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5134         remote_ost_nodsh && skip "remote OST with nodsh"
5135
5136         # get ost1 size - $FSNAME-OST0000
5137         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5138                 awk '{ print $4 }')
5139         # write 800M at maximum
5140         [[ $ost1_size -lt 2 ]] && ost1_size=2
5141         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5142
5143         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5144         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5145         local dd_pid=$!
5146
5147         # change max_pages_per_rpc while writing the file
5148         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5149         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5150         # loop until dd process exits
5151         while ps ax -opid | grep -wq $dd_pid; do
5152                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5153                 sleep $((RANDOM % 5 + 1))
5154         done
5155         # restore original max_pages_per_rpc
5156         $LCTL set_param $osc1_mppc=$orig_mppc
5157         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5158 }
5159 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5160
5161 test_50() {
5162         # bug 1485
5163         test_mkdir $DIR/$tdir
5164         cd $DIR/$tdir
5165         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5166 }
5167 run_test 50 "special situations: /proc symlinks  ==============="
5168
5169 test_51a() {    # was test_51
5170         # bug 1516 - create an empty entry right after ".." then split dir
5171         test_mkdir -c1 $DIR/$tdir
5172         touch $DIR/$tdir/foo
5173         $MCREATE $DIR/$tdir/bar
5174         rm $DIR/$tdir/foo
5175         createmany -m $DIR/$tdir/longfile 201
5176         FNUM=202
5177         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5178                 $MCREATE $DIR/$tdir/longfile$FNUM
5179                 FNUM=$(($FNUM + 1))
5180                 echo -n "+"
5181         done
5182         echo
5183         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5184 }
5185 run_test 51a "special situations: split htree with empty entry =="
5186
5187 cleanup_print_lfs_df () {
5188         trap 0
5189         $LFS df
5190         $LFS df -i
5191 }
5192
5193 test_51b() {
5194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5195
5196         local dir=$DIR/$tdir
5197         local nrdirs=$((65536 + 100))
5198
5199         # cleanup the directory
5200         rm -fr $dir
5201
5202         test_mkdir -c1 $dir
5203
5204         $LFS df
5205         $LFS df -i
5206         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5207         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5208         [[ $numfree -lt $nrdirs ]] &&
5209                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5210
5211         # need to check free space for the directories as well
5212         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5213         numfree=$(( blkfree / $(fs_inode_ksize) ))
5214         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5215
5216         trap cleanup_print_lfs_df EXIT
5217
5218         # create files
5219         createmany -d $dir/d $nrdirs || {
5220                 unlinkmany $dir/d $nrdirs
5221                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5222         }
5223
5224         # really created :
5225         nrdirs=$(ls -U $dir | wc -l)
5226
5227         # unlink all but 100 subdirectories, then check it still works
5228         local left=100
5229         local delete=$((nrdirs - left))
5230
5231         $LFS df
5232         $LFS df -i
5233
5234         # for ldiskfs the nlink count should be 1, but this is OSD specific
5235         # and so this is listed for informational purposes only
5236         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5237         unlinkmany -d $dir/d $delete ||
5238                 error "unlink of first $delete subdirs failed"
5239
5240         echo "nlink between: $(stat -c %h $dir)"
5241         local found=$(ls -U $dir | wc -l)
5242         [ $found -ne $left ] &&
5243                 error "can't find subdirs: found only $found, expected $left"
5244
5245         unlinkmany -d $dir/d $delete $left ||
5246                 error "unlink of second $left subdirs failed"
5247         # regardless of whether the backing filesystem tracks nlink accurately
5248         # or not, the nlink count shouldn't be more than "." and ".." here
5249         local after=$(stat -c %h $dir)
5250         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5251                 echo "nlink after: $after"
5252
5253         cleanup_print_lfs_df
5254 }
5255 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5256
5257 test_51d() {
5258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5259         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5260
5261         test_mkdir $DIR/$tdir
5262         createmany -o $DIR/$tdir/t- 1000
5263         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5264         for N in $(seq 0 $((OSTCOUNT - 1))); do
5265                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5266                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5267                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5268                         '($1 == '$N') { objs += 1 } \
5269                         END { printf("%0.0f", objs) }')
5270                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5271         done
5272         unlinkmany $DIR/$tdir/t- 1000
5273
5274         NLAST=0
5275         for N in $(seq 1 $((OSTCOUNT - 1))); do
5276                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5277                         error "OST $N has less objects vs OST $NLAST" \
5278                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5279                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5280                         error "OST $N has less objects vs OST $NLAST" \
5281                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5282
5283                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5284                         error "OST $N has less #0 objects vs OST $NLAST" \
5285                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5286                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5287                         error "OST $N has less #0 objects vs OST $NLAST" \
5288                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5289                 NLAST=$N
5290         done
5291         rm -f $TMP/$tfile
5292 }
5293 run_test 51d "check object distribution"
5294
5295 test_51e() {
5296         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5297                 skip_env "ldiskfs only test"
5298         fi
5299
5300         test_mkdir -c1 $DIR/$tdir
5301         test_mkdir -c1 $DIR/$tdir/d0
5302
5303         touch $DIR/$tdir/d0/foo
5304         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5305                 error "file exceed 65000 nlink limit!"
5306         unlinkmany $DIR/$tdir/d0/f- 65001
5307         return 0
5308 }
5309 run_test 51e "check file nlink limit"
5310
5311 test_51f() {
5312         test_mkdir $DIR/$tdir
5313
5314         local max=100000
5315         local ulimit_old=$(ulimit -n)
5316         local spare=20 # number of spare fd's for scripts/libraries, etc.
5317         local mdt=$($LFS getstripe -m $DIR/$tdir)
5318         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5319
5320         echo "MDT$mdt numfree=$numfree, max=$max"
5321         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5322         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5323                 while ! ulimit -n $((numfree + spare)); do
5324                         numfree=$((numfree * 3 / 4))
5325                 done
5326                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5327         else
5328                 echo "left ulimit at $ulimit_old"
5329         fi
5330
5331         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5332                 unlinkmany $DIR/$tdir/f $numfree
5333                 error "create+open $numfree files in $DIR/$tdir failed"
5334         }
5335         ulimit -n $ulimit_old
5336
5337         # if createmany exits at 120s there will be fewer than $numfree files
5338         unlinkmany $DIR/$tdir/f $numfree || true
5339 }
5340 run_test 51f "check many open files limit"
5341
5342 test_52a() {
5343         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5344         test_mkdir $DIR/$tdir
5345         touch $DIR/$tdir/foo
5346         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5347         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5348         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5349         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5350         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5351                                         error "link worked"
5352         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5353         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5354         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5355                                                      error "lsattr"
5356         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5357         cp -r $DIR/$tdir $TMP/
5358         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5359 }
5360 run_test 52a "append-only flag test (should return errors)"
5361
5362 test_52b() {
5363         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5364         test_mkdir $DIR/$tdir
5365         touch $DIR/$tdir/foo
5366         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5367         cat test > $DIR/$tdir/foo && error "cat test worked"
5368         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5369         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5370         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5371                                         error "link worked"
5372         echo foo >> $DIR/$tdir/foo && error "echo worked"
5373         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5374         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5375         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5376         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5377                                                         error "lsattr"
5378         chattr -i $DIR/$tdir/foo || error "chattr failed"
5379
5380         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5381 }
5382 run_test 52b "immutable flag test (should return errors) ======="
5383
5384 test_53() {
5385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5386         remote_mds_nodsh && skip "remote MDS with nodsh"
5387         remote_ost_nodsh && skip "remote OST with nodsh"
5388
5389         local param
5390         local param_seq
5391         local ostname
5392         local mds_last
5393         local mds_last_seq
5394         local ost_last
5395         local ost_last_seq
5396         local ost_last_id
5397         local ostnum
5398         local node
5399         local found=false
5400         local support_last_seq=true
5401
5402         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5403                 support_last_seq=false
5404
5405         # only test MDT0000
5406         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5407         local value
5408         for value in $(do_facet $SINGLEMDS \
5409                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5410                 param=$(echo ${value[0]} | cut -d "=" -f1)
5411                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5412
5413                 if $support_last_seq; then
5414                         param_seq=$(echo $param |
5415                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5416                         mds_last_seq=$(do_facet $SINGLEMDS \
5417                                        $LCTL get_param -n $param_seq)
5418                 fi
5419                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5420
5421                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5422                 node=$(facet_active_host ost$((ostnum+1)))
5423                 param="obdfilter.$ostname.last_id"
5424                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5425                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5426                         ost_last_id=$ost_last
5427
5428                         if $support_last_seq; then
5429                                 ost_last_id=$(echo $ost_last |
5430                                               awk -F':' '{print $2}' |
5431                                               sed -e "s/^0x//g")
5432                                 ost_last_seq=$(echo $ost_last |
5433                                                awk -F':' '{print $1}')
5434                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5435                         fi
5436
5437                         if [[ $ost_last_id != $mds_last ]]; then
5438                                 error "$ost_last_id != $mds_last"
5439                         else
5440                                 found=true
5441                                 break
5442                         fi
5443                 done
5444         done
5445         $found || error "can not match last_seq/last_id for $mdtosc"
5446         return 0
5447 }
5448 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5449
5450 test_54a() {
5451         perl -MSocket -e ';' || skip "no Socket perl module installed"
5452
5453         $SOCKETSERVER $DIR/socket ||
5454                 error "$SOCKETSERVER $DIR/socket failed: $?"
5455         $SOCKETCLIENT $DIR/socket ||
5456                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5457         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5458 }
5459 run_test 54a "unix domain socket test =========================="
5460
5461 test_54b() {
5462         f="$DIR/f54b"
5463         mknod $f c 1 3
5464         chmod 0666 $f
5465         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5466 }
5467 run_test 54b "char device works in lustre ======================"
5468
5469 find_loop_dev() {
5470         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5471         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5472         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5473
5474         for i in $(seq 3 7); do
5475                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5476                 LOOPDEV=$LOOPBASE$i
5477                 LOOPNUM=$i
5478                 break
5479         done
5480 }
5481
5482 cleanup_54c() {
5483         local rc=0
5484         loopdev="$DIR/loop54c"
5485
5486         trap 0
5487         $UMOUNT $DIR/$tdir || rc=$?
5488         losetup -d $loopdev || true
5489         losetup -d $LOOPDEV || true
5490         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5491         return $rc
5492 }
5493
5494 test_54c() {
5495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5496
5497         loopdev="$DIR/loop54c"
5498
5499         find_loop_dev
5500         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5501         trap cleanup_54c EXIT
5502         mknod $loopdev b 7 $LOOPNUM
5503         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5504         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5505         losetup $loopdev $DIR/$tfile ||
5506                 error "can't set up $loopdev for $DIR/$tfile"
5507         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5508         test_mkdir $DIR/$tdir
5509         mount -t ext2 $loopdev $DIR/$tdir ||
5510                 error "error mounting $loopdev on $DIR/$tdir"
5511         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5512                 error "dd write"
5513         df $DIR/$tdir
5514         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5515                 error "dd read"
5516         cleanup_54c
5517 }
5518 run_test 54c "block device works in lustre ====================="
5519
5520 test_54d() {
5521         f="$DIR/f54d"
5522         string="aaaaaa"
5523         mknod $f p
5524         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5525 }
5526 run_test 54d "fifo device works in lustre ======================"
5527
5528 test_54e() {
5529         f="$DIR/f54e"
5530         string="aaaaaa"
5531         cp -aL /dev/console $f
5532         echo $string > $f || error "echo $string to $f failed"
5533 }
5534 run_test 54e "console/tty device works in lustre ======================"
5535
5536 test_56a() {
5537         local numfiles=3
5538         local dir=$DIR/$tdir
5539
5540         rm -rf $dir
5541         test_mkdir -p $dir/dir
5542         for i in $(seq $numfiles); do
5543                 touch $dir/file$i
5544                 touch $dir/dir/file$i
5545         done
5546
5547         local numcomp=$($LFS getstripe --component-count $dir)
5548
5549         [[ $numcomp == 0 ]] && numcomp=1
5550
5551         # test lfs getstripe with --recursive
5552         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5553
5554         [[ $filenum -eq $((numfiles * 2)) ]] ||
5555                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5556         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5557         [[ $filenum -eq $numfiles ]] ||
5558                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5559         echo "$LFS getstripe showed obdidx or l_ost_idx"
5560
5561         # test lfs getstripe with file instead of dir
5562         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5563         [[ $filenum -eq 1 ]] ||
5564                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5565         echo "$LFS getstripe file1 passed"
5566
5567         #test lfs getstripe with --verbose
5568         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5569         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5570                 error "$LFS getstripe --verbose $dir: "\
5571                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5572         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5573                 error "$LFS getstripe $dir: showed lmm_magic"
5574
5575         #test lfs getstripe with -v prints lmm_fid
5576         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5577         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5578                 error "$LFS getstripe -v $dir: "\
5579                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5580         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5581                 error "$LFS getstripe $dir: showed lmm_fid by default"
5582         echo "$LFS getstripe --verbose passed"
5583
5584         #check for FID information
5585         local fid1=$($LFS getstripe --fid $dir/file1)
5586         local fid2=$($LFS getstripe --verbose $dir/file1 |
5587                      awk '/lmm_fid: / { print $2; exit; }')
5588         local fid3=$($LFS path2fid $dir/file1)
5589
5590         [ "$fid1" != "$fid2" ] &&
5591                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5592         [ "$fid1" != "$fid3" ] &&
5593                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5594         echo "$LFS getstripe --fid passed"
5595
5596         #test lfs getstripe with --obd
5597         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5598                 error "$LFS getstripe --obd wrong_uuid: should return error"
5599
5600         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5601
5602         local ostidx=1
5603         local obduuid=$(ostuuid_from_index $ostidx)
5604         local found=$($LFS getstripe -r --obd $obduuid $dir |
5605                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5606
5607         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5608         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5609                 ((filenum--))
5610         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5611                 ((filenum--))
5612
5613         [[ $found -eq $filenum ]] ||
5614                 error "$LFS getstripe --obd: found $found expect $filenum"
5615         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5616                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5617                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5618                 error "$LFS getstripe --obd: should not show file on other obd"
5619         echo "$LFS getstripe --obd passed"
5620 }
5621 run_test 56a "check $LFS getstripe"
5622
5623 test_56b() {
5624         local dir=$DIR/$tdir
5625         local numdirs=3
5626
5627         test_mkdir $dir
5628         for i in $(seq $numdirs); do
5629                 test_mkdir $dir/dir$i
5630         done
5631
5632         # test lfs getdirstripe default mode is non-recursion, which is
5633         # different from lfs getstripe
5634         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5635
5636         [[ $dircnt -eq 1 ]] ||
5637                 error "$LFS getdirstripe: found $dircnt, not 1"
5638         dircnt=$($LFS getdirstripe --recursive $dir |
5639                 grep -c lmv_stripe_count)
5640         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5641                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5642 }
5643 run_test 56b "check $LFS getdirstripe"
5644
5645 test_56c() {
5646         remote_ost_nodsh && skip "remote OST with nodsh"
5647
5648         local ost_idx=0
5649         local ost_name=$(ostname_from_index $ost_idx)
5650         local old_status=$(ost_dev_status $ost_idx)
5651         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5652
5653         [[ -z "$old_status" ]] ||
5654                 skip_env "OST $ost_name is in $old_status status"
5655
5656         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5657         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5658                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5659         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5660                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5661                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5662         fi
5663
5664         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5665                 error "$LFS df -v showing inactive devices"
5666         sleep_maxage
5667
5668         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5669
5670         [[ "$new_status" =~ "D" ]] ||
5671                 error "$ost_name status is '$new_status', missing 'D'"
5672         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5673                 [[ "$new_status" =~ "N" ]] ||
5674                         error "$ost_name status is '$new_status', missing 'N'"
5675         fi
5676         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5677                 [[ "$new_status" =~ "f" ]] ||
5678                         error "$ost_name status is '$new_status', missing 'f'"
5679         fi
5680
5681         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5682         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5683                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5684         [[ -z "$p" ]] && restore_lustre_params < $p || true
5685         sleep_maxage
5686
5687         new_status=$(ost_dev_status $ost_idx)
5688         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5689                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5690         # can't check 'f' as devices may actually be on flash
5691 }
5692 run_test 56c "check 'lfs df' showing device status"
5693
5694 test_56d() {
5695         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
5696         local osts=$($LFS df -v $MOUNT | grep -c OST)
5697
5698         $LFS df $MOUNT
5699
5700         (( mdts == MDSCOUNT )) ||
5701                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
5702         (( osts == OSTCOUNT )) ||
5703                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
5704 }
5705 run_test 56d "'lfs df -v' prints only configured devices"
5706
5707 NUMFILES=3
5708 NUMDIRS=3
5709 setup_56() {
5710         local local_tdir="$1"
5711         local local_numfiles="$2"
5712         local local_numdirs="$3"
5713         local dir_params="$4"
5714         local dir_stripe_params="$5"
5715
5716         if [ ! -d "$local_tdir" ] ; then
5717                 test_mkdir -p $dir_stripe_params $local_tdir
5718                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5719                 for i in $(seq $local_numfiles) ; do
5720                         touch $local_tdir/file$i
5721                 done
5722                 for i in $(seq $local_numdirs) ; do
5723                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5724                         for j in $(seq $local_numfiles) ; do
5725                                 touch $local_tdir/dir$i/file$j
5726                         done
5727                 done
5728         fi
5729 }
5730
5731 setup_56_special() {
5732         local local_tdir=$1
5733         local local_numfiles=$2
5734         local local_numdirs=$3
5735
5736         setup_56 $local_tdir $local_numfiles $local_numdirs
5737
5738         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5739                 for i in $(seq $local_numfiles) ; do
5740                         mknod $local_tdir/loop${i}b b 7 $i
5741                         mknod $local_tdir/null${i}c c 1 3
5742                         ln -s $local_tdir/file1 $local_tdir/link${i}
5743                 done
5744                 for i in $(seq $local_numdirs) ; do
5745                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5746                         mknod $local_tdir/dir$i/null${i}c c 1 3
5747                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5748                 done
5749         fi
5750 }
5751
5752 test_56g() {
5753         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5754         local expected=$(($NUMDIRS + 2))
5755
5756         setup_56 $dir $NUMFILES $NUMDIRS
5757
5758         # test lfs find with -name
5759         for i in $(seq $NUMFILES) ; do
5760                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5761
5762                 [ $nums -eq $expected ] ||
5763                         error "lfs find -name '*$i' $dir wrong: "\
5764                               "found $nums, expected $expected"
5765         done
5766 }
5767 run_test 56g "check lfs find -name"
5768
5769 test_56h() {
5770         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5771         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5772
5773         setup_56 $dir $NUMFILES $NUMDIRS
5774
5775         # test lfs find with ! -name
5776         for i in $(seq $NUMFILES) ; do
5777                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5778
5779                 [ $nums -eq $expected ] ||
5780                         error "lfs find ! -name '*$i' $dir wrong: "\
5781                               "found $nums, expected $expected"
5782         done
5783 }
5784 run_test 56h "check lfs find ! -name"
5785
5786 test_56i() {
5787         local dir=$DIR/$tdir
5788
5789         test_mkdir $dir
5790
5791         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5792         local out=$($cmd)
5793
5794         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5795 }
5796 run_test 56i "check 'lfs find -ost UUID' skips directories"
5797
5798 test_56j() {
5799         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5800
5801         setup_56_special $dir $NUMFILES $NUMDIRS
5802
5803         local expected=$((NUMDIRS + 1))
5804         local cmd="$LFS find -type d $dir"
5805         local nums=$($cmd | wc -l)
5806
5807         [ $nums -eq $expected ] ||
5808                 error "'$cmd' wrong: found $nums, expected $expected"
5809 }
5810 run_test 56j "check lfs find -type d"
5811
5812 test_56k() {
5813         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5814
5815         setup_56_special $dir $NUMFILES $NUMDIRS
5816
5817         local expected=$(((NUMDIRS + 1) * NUMFILES))
5818         local cmd="$LFS find -type f $dir"
5819         local nums=$($cmd | wc -l)
5820
5821         [ $nums -eq $expected ] ||
5822                 error "'$cmd' wrong: found $nums, expected $expected"
5823 }
5824 run_test 56k "check lfs find -type f"
5825
5826 test_56l() {
5827         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5828
5829         setup_56_special $dir $NUMFILES $NUMDIRS
5830
5831         local expected=$((NUMDIRS + NUMFILES))
5832         local cmd="$LFS find -type b $dir"
5833         local nums=$($cmd | wc -l)
5834
5835         [ $nums -eq $expected ] ||
5836                 error "'$cmd' wrong: found $nums, expected $expected"
5837 }
5838 run_test 56l "check lfs find -type b"
5839
5840 test_56m() {
5841         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5842
5843         setup_56_special $dir $NUMFILES $NUMDIRS
5844
5845         local expected=$((NUMDIRS + NUMFILES))
5846         local cmd="$LFS find -type c $dir"
5847         local nums=$($cmd | wc -l)
5848         [ $nums -eq $expected ] ||
5849                 error "'$cmd' wrong: found $nums, expected $expected"
5850 }
5851 run_test 56m "check lfs find -type c"
5852
5853 test_56n() {
5854         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5855         setup_56_special $dir $NUMFILES $NUMDIRS
5856
5857         local expected=$((NUMDIRS + NUMFILES))
5858         local cmd="$LFS find -type l $dir"
5859         local nums=$($cmd | wc -l)
5860
5861         [ $nums -eq $expected ] ||
5862                 error "'$cmd' wrong: found $nums, expected $expected"
5863 }
5864 run_test 56n "check lfs find -type l"
5865
5866 test_56o() {
5867         local dir=$DIR/$tdir
5868
5869         setup_56 $dir $NUMFILES $NUMDIRS
5870         utime $dir/file1 > /dev/null || error "utime (1)"
5871         utime $dir/file2 > /dev/null || error "utime (2)"
5872         utime $dir/dir1 > /dev/null || error "utime (3)"
5873         utime $dir/dir2 > /dev/null || error "utime (4)"
5874         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5875         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5876
5877         local expected=4
5878         local nums=$($LFS find -mtime +0 $dir | wc -l)
5879
5880         [ $nums -eq $expected ] ||
5881                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5882
5883         expected=12
5884         cmd="$LFS find -mtime 0 $dir"
5885         nums=$($cmd | wc -l)
5886         [ $nums -eq $expected ] ||
5887                 error "'$cmd' wrong: found $nums, expected $expected"
5888 }
5889 run_test 56o "check lfs find -mtime for old files"
5890
5891 test_56ob() {
5892         local dir=$DIR/$tdir
5893         local expected=1
5894         local count=0
5895
5896         # just to make sure there is something that won't be found
5897         test_mkdir $dir
5898         touch $dir/$tfile.now
5899
5900         for age in year week day hour min; do
5901                 count=$((count + 1))
5902
5903                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5904                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5905                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5906
5907                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5908                 local nums=$($cmd | wc -l)
5909                 [ $nums -eq $expected ] ||
5910                         error "'$cmd' wrong: found $nums, expected $expected"
5911
5912                 cmd="$LFS find $dir -atime $count${age:0:1}"
5913                 nums=$($cmd | wc -l)
5914                 [ $nums -eq $expected ] ||
5915                         error "'$cmd' wrong: found $nums, expected $expected"
5916         done
5917
5918         sleep 2
5919         cmd="$LFS find $dir -ctime +1s -type f"
5920         nums=$($cmd | wc -l)
5921         (( $nums == $count * 2 + 1)) ||
5922                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5923 }
5924 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5925
5926 test_newerXY_base() {
5927         local x=$1
5928         local y=$2
5929         local dir=$DIR/$tdir
5930         local ref
5931         local negref
5932
5933         if [ $y == "t" ]; then
5934                 if [ $x == "b" ]; then
5935                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5936                 else
5937                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5938                 fi
5939         else
5940                 ref=$DIR/$tfile.newer.$x$y
5941                 touch $ref || error "touch $ref failed"
5942         fi
5943         sleep 2
5944         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
5945         sleep 2
5946         if [ $y == "t" ]; then
5947                 if [ $x == "b" ]; then
5948                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5949                 else
5950                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5951                 fi
5952         else
5953                 negref=$DIR/$tfile.negnewer.$x$y
5954                 touch $negref || error "touch $negref failed"
5955         fi
5956
5957         local cmd="$LFS find $dir -newer$x$y $ref"
5958         local nums=$(eval $cmd | wc -l)
5959         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
5960
5961         [ $nums -eq $expected ] ||
5962                 error "'$cmd' wrong: found $nums, expected $expected"
5963
5964         cmd="$LFS find $dir ! -newer$x$y $negref"
5965         nums=$(eval $cmd | wc -l)
5966         [ $nums -eq $expected ] ||
5967                 error "'$cmd' wrong: found $nums, expected $expected"
5968
5969         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
5970         nums=$(eval $cmd | wc -l)
5971         [ $nums -eq $expected ] ||
5972                 error "'$cmd' wrong: found $nums, expected $expected"
5973
5974         rm -rf $DIR/*
5975 }
5976
5977 test_56oc() {
5978         test_newerXY_base "b" "t"
5979         test_newerXY_base "a" "a"
5980         test_newerXY_base "a" "m"
5981         test_newerXY_base "a" "c"
5982         test_newerXY_base "m" "a"
5983         test_newerXY_base "m" "m"
5984         test_newerXY_base "m" "c"
5985         test_newerXY_base "c" "a"
5986         test_newerXY_base "c" "m"
5987         test_newerXY_base "c" "c"
5988         test_newerXY_base "b" "b"
5989         test_newerXY_base "a" "t"
5990         test_newerXY_base "m" "t"
5991         test_newerXY_base "c" "t"
5992         test_newerXY_base "b" "t"
5993 }
5994 run_test 56oc "check lfs find -newerXY work"
5995
5996 btime_supported() {
5997         local dir=$DIR/$tdir
5998         local rc
5999
6000         mkdir -p $dir
6001         touch $dir/$tfile
6002         $LFS find $dir -btime -1d -type f
6003         rc=$?
6004         rm -rf $dir
6005         return $rc
6006 }
6007
6008 test_56od() {
6009         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6010                 ! btime_supported && skip "btime unsupported on MDS"
6011
6012         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6013                 ! btime_supported && skip "btime unsupported on clients"
6014
6015         local dir=$DIR/$tdir
6016         local ref=$DIR/$tfile.ref
6017         local negref=$DIR/$tfile.negref
6018
6019         mkdir $dir || error "mkdir $dir failed"
6020         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6021         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6022         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6023         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6024         touch $ref || error "touch $ref failed"
6025         # sleep 3 seconds at least
6026         sleep 3
6027
6028         local before=$(do_facet mds1 date +%s)
6029         local skew=$(($(date +%s) - before + 1))
6030
6031         if (( skew < 0 && skew > -5 )); then
6032                 sleep $((0 - skew + 1))
6033                 skew=0
6034         fi
6035
6036         # Set the dir stripe params to limit files all on MDT0,
6037         # otherwise we need to calc the max clock skew between
6038         # the client and MDTs.
6039         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6040         sleep 2
6041         touch $negref || error "touch $negref failed"
6042
6043         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6044         local nums=$($cmd | wc -l)
6045         local expected=$(((NUMFILES + 1) * NUMDIRS))
6046
6047         [ $nums -eq $expected ] ||
6048                 error "'$cmd' wrong: found $nums, expected $expected"
6049
6050         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6051         nums=$($cmd | wc -l)
6052         expected=$((NUMFILES + 1))
6053         [ $nums -eq $expected ] ||
6054                 error "'$cmd' wrong: found $nums, expected $expected"
6055
6056         [ $skew -lt 0 ] && return
6057
6058         local after=$(do_facet mds1 date +%s)
6059         local age=$((after - before + 1 + skew))
6060
6061         cmd="$LFS find $dir -btime -${age}s -type f"
6062         nums=$($cmd | wc -l)
6063         expected=$(((NUMFILES + 1) * NUMDIRS))
6064
6065         echo "Clock skew between client and server: $skew, age:$age"
6066         [ $nums -eq $expected ] ||
6067                 error "'$cmd' wrong: found $nums, expected $expected"
6068
6069         expected=$(($NUMDIRS + 1))
6070         cmd="$LFS find $dir -btime -${age}s -type d"
6071         nums=$($cmd | wc -l)
6072         [ $nums -eq $expected ] ||
6073                 error "'$cmd' wrong: found $nums, expected $expected"
6074         rm -f $ref $negref || error "Failed to remove $ref $negref"
6075 }
6076 run_test 56od "check lfs find -btime with units"
6077
6078 test_56p() {
6079         [ $RUNAS_ID -eq $UID ] &&
6080                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6081
6082         local dir=$DIR/$tdir
6083
6084         setup_56 $dir $NUMFILES $NUMDIRS
6085         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6086
6087         local expected=$NUMFILES
6088         local cmd="$LFS find -uid $RUNAS_ID $dir"
6089         local nums=$($cmd | wc -l)
6090
6091         [ $nums -eq $expected ] ||
6092                 error "'$cmd' wrong: found $nums, expected $expected"
6093
6094         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6095         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6096         nums=$($cmd | wc -l)
6097         [ $nums -eq $expected ] ||
6098                 error "'$cmd' wrong: found $nums, expected $expected"
6099 }
6100 run_test 56p "check lfs find -uid and ! -uid"
6101
6102 test_56q() {
6103         [ $RUNAS_ID -eq $UID ] &&
6104                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6105
6106         local dir=$DIR/$tdir
6107
6108         setup_56 $dir $NUMFILES $NUMDIRS
6109         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6110
6111         local expected=$NUMFILES
6112         local cmd="$LFS find -gid $RUNAS_GID $dir"
6113         local nums=$($cmd | wc -l)
6114
6115         [ $nums -eq $expected ] ||
6116                 error "'$cmd' wrong: found $nums, expected $expected"
6117
6118         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6119         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6120         nums=$($cmd | wc -l)
6121         [ $nums -eq $expected ] ||
6122                 error "'$cmd' wrong: found $nums, expected $expected"
6123 }
6124 run_test 56q "check lfs find -gid and ! -gid"
6125
6126 test_56r() {
6127         local dir=$DIR/$tdir
6128
6129         setup_56 $dir $NUMFILES $NUMDIRS
6130
6131         local expected=12
6132         local cmd="$LFS find -size 0 -type f -lazy $dir"
6133         local nums=$($cmd | wc -l)
6134
6135         [ $nums -eq $expected ] ||
6136                 error "'$cmd' wrong: found $nums, expected $expected"
6137         cmd="$LFS find -size 0 -type f $dir"
6138         nums=$($cmd | wc -l)
6139         [ $nums -eq $expected ] ||
6140                 error "'$cmd' wrong: found $nums, expected $expected"
6141
6142         expected=0
6143         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6144         nums=$($cmd | wc -l)
6145         [ $nums -eq $expected ] ||
6146                 error "'$cmd' wrong: found $nums, expected $expected"
6147         cmd="$LFS find ! -size 0 -type f $dir"
6148         nums=$($cmd | wc -l)
6149         [ $nums -eq $expected ] ||
6150                 error "'$cmd' wrong: found $nums, expected $expected"
6151
6152         echo "test" > $dir/$tfile
6153         echo "test2" > $dir/$tfile.2 && sync
6154         expected=1
6155         cmd="$LFS find -size 5 -type f -lazy $dir"
6156         nums=$($cmd | wc -l)
6157         [ $nums -eq $expected ] ||
6158                 error "'$cmd' wrong: found $nums, expected $expected"
6159         cmd="$LFS find -size 5 -type f $dir"
6160         nums=$($cmd | wc -l)
6161         [ $nums -eq $expected ] ||
6162                 error "'$cmd' wrong: found $nums, expected $expected"
6163
6164         expected=1
6165         cmd="$LFS find -size +5 -type f -lazy $dir"
6166         nums=$($cmd | wc -l)
6167         [ $nums -eq $expected ] ||
6168                 error "'$cmd' wrong: found $nums, expected $expected"
6169         cmd="$LFS find -size +5 -type f $dir"
6170         nums=$($cmd | wc -l)
6171         [ $nums -eq $expected ] ||
6172                 error "'$cmd' wrong: found $nums, expected $expected"
6173
6174         expected=2
6175         cmd="$LFS find -size +0 -type f -lazy $dir"
6176         nums=$($cmd | wc -l)
6177         [ $nums -eq $expected ] ||
6178                 error "'$cmd' wrong: found $nums, expected $expected"
6179         cmd="$LFS find -size +0 -type f $dir"
6180         nums=$($cmd | wc -l)
6181         [ $nums -eq $expected ] ||
6182                 error "'$cmd' wrong: found $nums, expected $expected"
6183
6184         expected=2
6185         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6186         nums=$($cmd | wc -l)
6187         [ $nums -eq $expected ] ||
6188                 error "'$cmd' wrong: found $nums, expected $expected"
6189         cmd="$LFS find ! -size -5 -type f $dir"
6190         nums=$($cmd | wc -l)
6191         [ $nums -eq $expected ] ||
6192                 error "'$cmd' wrong: found $nums, expected $expected"
6193
6194         expected=12
6195         cmd="$LFS find -size -5 -type f -lazy $dir"
6196         nums=$($cmd | wc -l)
6197         [ $nums -eq $expected ] ||
6198                 error "'$cmd' wrong: found $nums, expected $expected"
6199         cmd="$LFS find -size -5 -type f $dir"
6200         nums=$($cmd | wc -l)
6201         [ $nums -eq $expected ] ||
6202                 error "'$cmd' wrong: found $nums, expected $expected"
6203 }
6204 run_test 56r "check lfs find -size works"
6205
6206 test_56ra_sub() {
6207         local expected=$1
6208         local glimpses=$2
6209         local cmd="$3"
6210
6211         cancel_lru_locks $OSC
6212
6213         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6214         local nums=$($cmd | wc -l)
6215
6216         [ $nums -eq $expected ] ||
6217                 error "'$cmd' wrong: found $nums, expected $expected"
6218
6219         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6220
6221         if (( rpcs_before + glimpses != rpcs_after )); then
6222                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6223                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6224
6225                 if [[ $glimpses == 0 ]]; then
6226                         error "'$cmd' should not send glimpse RPCs to OST"
6227                 else
6228                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6229                 fi
6230         fi
6231 }
6232
6233 test_56ra() {
6234         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6235                 skip "MDS < 2.12.58 doesn't return LSOM data"
6236         local dir=$DIR/$tdir
6237
6238         [[ $OSC == "mdc" ]] && skip "DoM files" && return
6239
6240         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6241         # open and close all files to ensure LSOM is updated
6242         cancel_lru_locks $OSC
6243         find $dir -type f | xargs cat > /dev/null
6244
6245         #   expect_found  glimpse_rpcs  command_to_run
6246         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6247         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6248         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6249         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6250
6251         echo "test" > $dir/$tfile
6252         echo "test2" > $dir/$tfile.2 && sync
6253         cancel_lru_locks $OSC
6254         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6255
6256         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6257         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6258         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6259         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6260
6261         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6262         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6263         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6264         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6265         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6266         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6267 }
6268 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6269
6270 test_56rb() {
6271         local dir=$DIR/$tdir
6272         local tmp=$TMP/$tfile.log
6273         local mdt_idx;
6274
6275         test_mkdir -p $dir || error "failed to mkdir $dir"
6276         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6277                 error "failed to setstripe $dir/$tfile"
6278         mdt_idx=$($LFS getdirstripe -i $dir)
6279         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6280
6281         stack_trap "rm -f $tmp" EXIT
6282         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6283         ! grep -q obd_uuid $tmp ||
6284                 error "failed to find --size +100K --ost 0 $dir"
6285         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6286         ! grep -q obd_uuid $tmp ||
6287                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6288 }
6289 run_test 56rb "check lfs find --size --ost/--mdt works"
6290
6291 test_56s() { # LU-611 #LU-9369
6292         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6293
6294         local dir=$DIR/$tdir
6295         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6296
6297         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6298         for i in $(seq $NUMDIRS); do
6299                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6300         done
6301
6302         local expected=$NUMDIRS
6303         local cmd="$LFS find -c $OSTCOUNT $dir"
6304         local nums=$($cmd | wc -l)
6305
6306         [ $nums -eq $expected ] || {
6307                 $LFS getstripe -R $dir
6308                 error "'$cmd' wrong: found $nums, expected $expected"
6309         }
6310
6311         expected=$((NUMDIRS + onestripe))
6312         cmd="$LFS find -stripe-count +0 -type f $dir"
6313         nums=$($cmd | wc -l)
6314         [ $nums -eq $expected ] || {
6315                 $LFS getstripe -R $dir
6316                 error "'$cmd' wrong: found $nums, expected $expected"
6317         }
6318
6319         expected=$onestripe
6320         cmd="$LFS find -stripe-count 1 -type f $dir"
6321         nums=$($cmd | wc -l)
6322         [ $nums -eq $expected ] || {
6323                 $LFS getstripe -R $dir
6324                 error "'$cmd' wrong: found $nums, expected $expected"
6325         }
6326
6327         cmd="$LFS find -stripe-count -2 -type f $dir"
6328         nums=$($cmd | wc -l)
6329         [ $nums -eq $expected ] || {
6330                 $LFS getstripe -R $dir
6331                 error "'$cmd' wrong: found $nums, expected $expected"
6332         }
6333
6334         expected=0
6335         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6336         nums=$($cmd | wc -l)
6337         [ $nums -eq $expected ] || {
6338                 $LFS getstripe -R $dir
6339                 error "'$cmd' wrong: found $nums, expected $expected"
6340         }
6341 }
6342 run_test 56s "check lfs find -stripe-count works"
6343
6344 test_56t() { # LU-611 #LU-9369
6345         local dir=$DIR/$tdir
6346
6347         setup_56 $dir 0 $NUMDIRS
6348         for i in $(seq $NUMDIRS); do
6349                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6350         done
6351
6352         local expected=$NUMDIRS
6353         local cmd="$LFS find -S 8M $dir"
6354         local nums=$($cmd | wc -l)
6355
6356         [ $nums -eq $expected ] || {
6357                 $LFS getstripe -R $dir
6358                 error "'$cmd' wrong: found $nums, expected $expected"
6359         }
6360         rm -rf $dir
6361
6362         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6363
6364         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6365
6366         expected=$(((NUMDIRS + 1) * NUMFILES))
6367         cmd="$LFS find -stripe-size 512k -type f $dir"
6368         nums=$($cmd | wc -l)
6369         [ $nums -eq $expected ] ||
6370                 error "'$cmd' wrong: found $nums, expected $expected"
6371
6372         cmd="$LFS find -stripe-size +320k -type f $dir"
6373         nums=$($cmd | wc -l)
6374         [ $nums -eq $expected ] ||
6375                 error "'$cmd' wrong: found $nums, expected $expected"
6376
6377         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6378         cmd="$LFS find -stripe-size +200k -type f $dir"
6379         nums=$($cmd | wc -l)
6380         [ $nums -eq $expected ] ||
6381                 error "'$cmd' wrong: found $nums, expected $expected"
6382
6383         cmd="$LFS find -stripe-size -640k -type f $dir"
6384         nums=$($cmd | wc -l)
6385         [ $nums -eq $expected ] ||
6386                 error "'$cmd' wrong: found $nums, expected $expected"
6387
6388         expected=4
6389         cmd="$LFS find -stripe-size 256k -type f $dir"
6390         nums=$($cmd | wc -l)
6391         [ $nums -eq $expected ] ||
6392                 error "'$cmd' wrong: found $nums, expected $expected"
6393
6394         cmd="$LFS find -stripe-size -320k -type f $dir"
6395         nums=$($cmd | wc -l)
6396         [ $nums -eq $expected ] ||
6397                 error "'$cmd' wrong: found $nums, expected $expected"
6398
6399         expected=0
6400         cmd="$LFS find -stripe-size 1024k -type f $dir"
6401         nums=$($cmd | wc -l)
6402         [ $nums -eq $expected ] ||
6403                 error "'$cmd' wrong: found $nums, expected $expected"
6404 }
6405 run_test 56t "check lfs find -stripe-size works"
6406
6407 test_56u() { # LU-611
6408         local dir=$DIR/$tdir
6409
6410         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6411
6412         if [[ $OSTCOUNT -gt 1 ]]; then
6413                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6414                 onestripe=4
6415         else
6416                 onestripe=0
6417         fi
6418
6419         local expected=$(((NUMDIRS + 1) * NUMFILES))
6420         local cmd="$LFS find -stripe-index 0 -type f $dir"
6421         local nums=$($cmd | wc -l)
6422
6423         [ $nums -eq $expected ] ||
6424                 error "'$cmd' wrong: found $nums, expected $expected"
6425
6426         expected=$onestripe
6427         cmd="$LFS find -stripe-index 1 -type f $dir"
6428         nums=$($cmd | wc -l)
6429         [ $nums -eq $expected ] ||
6430                 error "'$cmd' wrong: found $nums, expected $expected"
6431
6432         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6433         nums=$($cmd | wc -l)
6434         [ $nums -eq $expected ] ||
6435                 error "'$cmd' wrong: found $nums, expected $expected"
6436
6437         expected=0
6438         # This should produce an error and not return any files
6439         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6440         nums=$($cmd 2>/dev/null | wc -l)
6441         [ $nums -eq $expected ] ||
6442                 error "'$cmd' wrong: found $nums, expected $expected"
6443
6444         if [[ $OSTCOUNT -gt 1 ]]; then
6445                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6446                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6447                 nums=$($cmd | wc -l)
6448                 [ $nums -eq $expected ] ||
6449                         error "'$cmd' wrong: found $nums, expected $expected"
6450         fi
6451 }
6452 run_test 56u "check lfs find -stripe-index works"
6453
6454 test_56v() {
6455         local mdt_idx=0
6456         local dir=$DIR/$tdir
6457
6458         setup_56 $dir $NUMFILES $NUMDIRS
6459
6460         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6461         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6462
6463         for file in $($LFS find -m $UUID $dir); do
6464                 file_midx=$($LFS getstripe -m $file)
6465                 [ $file_midx -eq $mdt_idx ] ||
6466                         error "lfs find -m $UUID != getstripe -m $file_midx"
6467         done
6468 }
6469 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6470
6471 test_56w() {
6472         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6474
6475         local dir=$DIR/$tdir
6476
6477         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6478
6479         local stripe_size=$($LFS getstripe -S -d $dir) ||
6480                 error "$LFS getstripe -S -d $dir failed"
6481         stripe_size=${stripe_size%% *}
6482
6483         local file_size=$((stripe_size * OSTCOUNT))
6484         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6485         local required_space=$((file_num * file_size))
6486         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6487                            head -n1)
6488         [[ $free_space -le $((required_space / 1024)) ]] &&
6489                 skip_env "need $required_space, have $free_space kbytes"
6490
6491         local dd_bs=65536
6492         local dd_count=$((file_size / dd_bs))
6493
6494         # write data into the files
6495         local i
6496         local j
6497         local file
6498
6499         for i in $(seq $NUMFILES); do
6500                 file=$dir/file$i
6501                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6502                         error "write data into $file failed"
6503         done
6504         for i in $(seq $NUMDIRS); do
6505                 for j in $(seq $NUMFILES); do
6506                         file=$dir/dir$i/file$j
6507                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6508                                 error "write data into $file failed"
6509                 done
6510         done
6511
6512         # $LFS_MIGRATE will fail if hard link migration is unsupported
6513         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6514                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6515                         error "creating links to $dir/dir1/file1 failed"
6516         fi
6517
6518         local expected=-1
6519
6520         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6521
6522         # lfs_migrate file
6523         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6524
6525         echo "$cmd"
6526         eval $cmd || error "$cmd failed"
6527
6528         check_stripe_count $dir/file1 $expected
6529
6530         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6531         then
6532                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6533                 # OST 1 if it is on OST 0. This file is small enough to
6534                 # be on only one stripe.
6535                 file=$dir/migr_1_ost
6536                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6537                         error "write data into $file failed"
6538                 local obdidx=$($LFS getstripe -i $file)
6539                 local oldmd5=$(md5sum $file)
6540                 local newobdidx=0
6541
6542                 [[ $obdidx -eq 0 ]] && newobdidx=1
6543                 cmd="$LFS migrate -i $newobdidx $file"
6544                 echo $cmd
6545                 eval $cmd || error "$cmd failed"
6546
6547                 local realobdix=$($LFS getstripe -i $file)
6548                 local newmd5=$(md5sum $file)
6549
6550                 [[ $newobdidx -ne $realobdix ]] &&
6551                         error "new OST is different (was=$obdidx, "\
6552                               "wanted=$newobdidx, got=$realobdix)"
6553                 [[ "$oldmd5" != "$newmd5" ]] &&
6554                         error "md5sum differ: $oldmd5, $newmd5"
6555         fi
6556
6557         # lfs_migrate dir
6558         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6559         echo "$cmd"
6560         eval $cmd || error "$cmd failed"
6561
6562         for j in $(seq $NUMFILES); do
6563                 check_stripe_count $dir/dir1/file$j $expected
6564         done
6565
6566         # lfs_migrate works with lfs find
6567         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6568              $LFS_MIGRATE -y -c $expected"
6569         echo "$cmd"
6570         eval $cmd || error "$cmd failed"
6571
6572         for i in $(seq 2 $NUMFILES); do
6573                 check_stripe_count $dir/file$i $expected
6574         done
6575         for i in $(seq 2 $NUMDIRS); do
6576                 for j in $(seq $NUMFILES); do
6577                 check_stripe_count $dir/dir$i/file$j $expected
6578                 done
6579         done
6580 }
6581 run_test 56w "check lfs_migrate -c stripe_count works"
6582
6583 test_56wb() {
6584         local file1=$DIR/$tdir/file1
6585         local create_pool=false
6586         local initial_pool=$($LFS getstripe -p $DIR)
6587         local pool_list=()
6588         local pool=""
6589
6590         echo -n "Creating test dir..."
6591         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6592         echo "done."
6593
6594         echo -n "Creating test file..."
6595         touch $file1 || error "cannot create file"
6596         echo "done."
6597
6598         echo -n "Detecting existing pools..."
6599         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6600
6601         if [ ${#pool_list[@]} -gt 0 ]; then
6602                 echo "${pool_list[@]}"
6603                 for thispool in "${pool_list[@]}"; do
6604                         if [[ -z "$initial_pool" ||
6605                               "$initial_pool" != "$thispool" ]]; then
6606                                 pool="$thispool"
6607                                 echo "Using existing pool '$pool'"
6608                                 break
6609                         fi
6610                 done
6611         else
6612                 echo "none detected."
6613         fi
6614         if [ -z "$pool" ]; then
6615                 pool=${POOL:-testpool}
6616                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6617                 echo -n "Creating pool '$pool'..."
6618                 create_pool=true
6619                 pool_add $pool &> /dev/null ||
6620                         error "pool_add failed"
6621                 echo "done."
6622
6623                 echo -n "Adding target to pool..."
6624                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6625                         error "pool_add_targets failed"
6626                 echo "done."
6627         fi
6628
6629         echo -n "Setting pool using -p option..."
6630         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6631                 error "migrate failed rc = $?"
6632         echo "done."
6633
6634         echo -n "Verifying test file is in pool after migrating..."
6635         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6636                 error "file was not migrated to pool $pool"
6637         echo "done."
6638
6639         echo -n "Removing test file from pool '$pool'..."
6640         # "lfs migrate $file" won't remove the file from the pool
6641         # until some striping information is changed.
6642         $LFS migrate -c 1 $file1 &> /dev/null ||
6643                 error "cannot remove from pool"
6644         [ "$($LFS getstripe -p $file1)" ] &&
6645                 error "pool still set"
6646         echo "done."
6647
6648         echo -n "Setting pool using --pool option..."
6649         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6650                 error "migrate failed rc = $?"
6651         echo "done."
6652
6653         # Clean up
6654         rm -f $file1
6655         if $create_pool; then
6656                 destroy_test_pools 2> /dev/null ||
6657                         error "destroy test pools failed"
6658         fi
6659 }
6660 run_test 56wb "check lfs_migrate pool support"
6661
6662 test_56wc() {
6663         local file1="$DIR/$tdir/file1"
6664         local parent_ssize
6665         local parent_scount
6666         local cur_ssize
6667         local cur_scount
6668         local orig_ssize
6669
6670         echo -n "Creating test dir..."
6671         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6672         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6673                 error "cannot set stripe by '-S 1M -c 1'"
6674         echo "done"
6675
6676         echo -n "Setting initial stripe for test file..."
6677         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6678                 error "cannot set stripe"
6679         cur_ssize=$($LFS getstripe -S "$file1")
6680         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6681         echo "done."
6682
6683         # File currently set to -S 512K -c 1
6684
6685         # Ensure -c and -S options are rejected when -R is set
6686         echo -n "Verifying incompatible options are detected..."
6687         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6688                 error "incompatible -c and -R options not detected"
6689         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6690                 error "incompatible -S and -R options not detected"
6691         echo "done."
6692
6693         # Ensure unrecognized options are passed through to 'lfs migrate'
6694         echo -n "Verifying -S option is passed through to lfs migrate..."
6695         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6696                 error "migration failed"
6697         cur_ssize=$($LFS getstripe -S "$file1")
6698         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6699         echo "done."
6700
6701         # File currently set to -S 1M -c 1
6702
6703         # Ensure long options are supported
6704         echo -n "Verifying long options supported..."
6705         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6706                 error "long option without argument not supported"
6707         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6708                 error "long option with argument not supported"
6709         cur_ssize=$($LFS getstripe -S "$file1")
6710         [ $cur_ssize -eq 524288 ] ||
6711                 error "migrate --stripe-size $cur_ssize != 524288"
6712         echo "done."
6713
6714         # File currently set to -S 512K -c 1
6715
6716         if [ "$OSTCOUNT" -gt 1 ]; then
6717                 echo -n "Verifying explicit stripe count can be set..."
6718                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6719                         error "migrate failed"
6720                 cur_scount=$($LFS getstripe -c "$file1")
6721                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
6722                 echo "done."
6723         fi
6724
6725         # File currently set to -S 512K -c 1 or -S 512K -c 2
6726
6727         # Ensure parent striping is used if -R is set, and no stripe
6728         # count or size is specified
6729         echo -n "Setting stripe for parent directory..."
6730         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6731                 error "cannot set stripe '-S 2M -c 1'"
6732         echo "done."
6733
6734         echo -n "Verifying restripe option uses parent stripe settings..."
6735         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6736         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
6737         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6738                 error "migrate failed"
6739         cur_ssize=$($LFS getstripe -S "$file1")
6740         [ $cur_ssize -eq $parent_ssize ] ||
6741                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
6742         cur_scount=$($LFS getstripe -c "$file1")
6743         [ $cur_scount -eq $parent_scount ] ||
6744                 error "migrate -R stripe_count $cur_scount != $parent_scount"
6745         echo "done."
6746
6747         # File currently set to -S 1M -c 1
6748
6749         # Ensure striping is preserved if -R is not set, and no stripe
6750         # count or size is specified
6751         echo -n "Verifying striping size preserved when not specified..."
6752         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
6753         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6754                 error "cannot set stripe on parent directory"
6755         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6756                 error "migrate failed"
6757         cur_ssize=$($LFS getstripe -S "$file1")
6758         [ $cur_ssize -eq $orig_ssize ] ||
6759                 error "migrate by default $cur_ssize != $orig_ssize"
6760         echo "done."
6761
6762         # Ensure file name properly detected when final option has no argument
6763         echo -n "Verifying file name properly detected..."
6764         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6765                 error "file name interpreted as option argument"
6766         echo "done."
6767
6768         # Clean up
6769         rm -f "$file1"
6770 }
6771 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6772
6773 test_56wd() {
6774         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6775
6776         local file1=$DIR/$tdir/file1
6777
6778         echo -n "Creating test dir..."
6779         test_mkdir $DIR/$tdir || error "cannot create dir"
6780         echo "done."
6781
6782         echo -n "Creating test file..."
6783         touch $file1
6784         echo "done."
6785
6786         # Ensure 'lfs migrate' will fail by using a non-existent option,
6787         # and make sure rsync is not called to recover
6788         echo -n "Make sure --no-rsync option works..."
6789         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6790                 grep -q 'refusing to fall back to rsync' ||
6791                 error "rsync was called with --no-rsync set"
6792         echo "done."
6793
6794         # Ensure rsync is called without trying 'lfs migrate' first
6795         echo -n "Make sure --rsync option works..."
6796         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6797                 grep -q 'falling back to rsync' &&
6798                 error "lfs migrate was called with --rsync set"
6799         echo "done."
6800
6801         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6802         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6803                 grep -q 'at the same time' ||
6804                 error "--rsync and --no-rsync accepted concurrently"
6805         echo "done."
6806
6807         # Clean up
6808         rm -f $file1
6809 }
6810 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6811
6812 test_56we() {
6813         local td=$DIR/$tdir
6814         local tf=$td/$tfile
6815
6816         test_mkdir $td || error "cannot create $td"
6817         touch $tf || error "cannot touch $tf"
6818
6819         echo -n "Make sure --non-direct|-D works..."
6820         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
6821                 grep -q "lfs migrate --non-direct" ||
6822                 error "--non-direct option cannot work correctly"
6823         $LFS_MIGRATE -y -D -v $tf 2>&1 |
6824                 grep -q "lfs migrate -D" ||
6825                 error "-D option cannot work correctly"
6826         echo "done."
6827 }
6828 run_test 56we "check lfs_migrate --non-direct|-D support"
6829
6830 test_56x() {
6831         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6832         check_swap_layouts_support
6833
6834         local dir=$DIR/$tdir
6835         local ref1=/etc/passwd
6836         local file1=$dir/file1
6837
6838         test_mkdir $dir || error "creating dir $dir"
6839         $LFS setstripe -c 2 $file1
6840         cp $ref1 $file1
6841         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6842         stripe=$($LFS getstripe -c $file1)
6843         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6844         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6845
6846         # clean up
6847         rm -f $file1
6848 }
6849 run_test 56x "lfs migration support"
6850
6851 test_56xa() {
6852         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6853         check_swap_layouts_support
6854
6855         local dir=$DIR/$tdir/$testnum
6856
6857         test_mkdir -p $dir
6858
6859         local ref1=/etc/passwd
6860         local file1=$dir/file1
6861
6862         $LFS setstripe -c 2 $file1
6863         cp $ref1 $file1
6864         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6865
6866         local stripe=$($LFS getstripe -c $file1)
6867
6868         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6869         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6870
6871         # clean up
6872         rm -f $file1
6873 }
6874 run_test 56xa "lfs migration --block support"
6875
6876 check_migrate_links() {
6877         local dir="$1"
6878         local file1="$dir/file1"
6879         local begin="$2"
6880         local count="$3"
6881         local runas="$4"
6882         local total_count=$(($begin + $count - 1))
6883         local symlink_count=10
6884         local uniq_count=10
6885
6886         if [ ! -f "$file1" ]; then
6887                 echo -n "creating initial file..."
6888                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6889                         error "cannot setstripe initial file"
6890                 echo "done"
6891
6892                 echo -n "creating symlinks..."
6893                 for s in $(seq 1 $symlink_count); do
6894                         ln -s "$file1" "$dir/slink$s" ||
6895                                 error "cannot create symlinks"
6896                 done
6897                 echo "done"
6898
6899                 echo -n "creating nonlinked files..."
6900                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6901                         error "cannot create nonlinked files"
6902                 echo "done"
6903         fi
6904
6905         # create hard links
6906         if [ ! -f "$dir/file$total_count" ]; then
6907                 echo -n "creating hard links $begin:$total_count..."
6908                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6909                         /dev/null || error "cannot create hard links"
6910                 echo "done"
6911         fi
6912
6913         echo -n "checking number of hard links listed in xattrs..."
6914         local fid=$($LFS getstripe -F "$file1")
6915         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6916
6917         echo "${#paths[*]}"
6918         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6919                         skip "hard link list has unexpected size, skipping test"
6920         fi
6921         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6922                         error "link names should exceed xattrs size"
6923         fi
6924
6925         echo -n "migrating files..."
6926         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
6927         local rc=$?
6928         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6929         echo "done"
6930
6931         # make sure all links have been properly migrated
6932         echo -n "verifying files..."
6933         fid=$($LFS getstripe -F "$file1") ||
6934                 error "cannot get fid for file $file1"
6935         for i in $(seq 2 $total_count); do
6936                 local fid2=$($LFS getstripe -F $dir/file$i)
6937
6938                 [ "$fid2" == "$fid" ] ||
6939                         error "migrated hard link has mismatched FID"
6940         done
6941
6942         # make sure hard links were properly detected, and migration was
6943         # performed only once for the entire link set; nonlinked files should
6944         # also be migrated
6945         local actual=$(grep -c 'done' <<< "$migrate_out")
6946         local expected=$(($uniq_count + 1))
6947
6948         [ "$actual" -eq  "$expected" ] ||
6949                 error "hard links individually migrated ($actual != $expected)"
6950
6951         # make sure the correct number of hard links are present
6952         local hardlinks=$(stat -c '%h' "$file1")
6953
6954         [ $hardlinks -eq $total_count ] ||
6955                 error "num hard links $hardlinks != $total_count"
6956         echo "done"
6957
6958         return 0
6959 }
6960
6961 test_56xb() {
6962         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6963                 skip "Need MDS version at least 2.10.55"
6964
6965         local dir="$DIR/$tdir"
6966
6967         test_mkdir "$dir" || error "cannot create dir $dir"
6968
6969         echo "testing lfs migrate mode when all links fit within xattrs"
6970         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6971
6972         echo "testing rsync mode when all links fit within xattrs"
6973         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6974
6975         echo "testing lfs migrate mode when all links do not fit within xattrs"
6976         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
6977
6978         echo "testing rsync mode when all links do not fit within xattrs"
6979         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
6980
6981         chown -R $RUNAS_ID $dir
6982         echo "testing non-root lfs migrate mode when not all links are in xattr"
6983         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
6984
6985         # clean up
6986         rm -rf $dir
6987 }
6988 run_test 56xb "lfs migration hard link support"
6989
6990 test_56xc() {
6991         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6992
6993         local dir="$DIR/$tdir"
6994
6995         test_mkdir "$dir" || error "cannot create dir $dir"
6996
6997         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
6998         echo -n "Setting initial stripe for 20MB test file..."
6999         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7000                 error "cannot setstripe 20MB file"
7001         echo "done"
7002         echo -n "Sizing 20MB test file..."
7003         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7004         echo "done"
7005         echo -n "Verifying small file autostripe count is 1..."
7006         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7007                 error "cannot migrate 20MB file"
7008         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7009                 error "cannot get stripe for $dir/20mb"
7010         [ $stripe_count -eq 1 ] ||
7011                 error "unexpected stripe count $stripe_count for 20MB file"
7012         rm -f "$dir/20mb"
7013         echo "done"
7014
7015         # Test 2: File is small enough to fit within the available space on
7016         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7017         # have at least an additional 1KB for each desired stripe for test 3
7018         echo -n "Setting stripe for 1GB test file..."
7019         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7020         echo "done"
7021         echo -n "Sizing 1GB test file..."
7022         # File size is 1GB + 3KB
7023         truncate "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7024         echo "done"
7025
7026         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7027         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7028         if (( avail > 524288 * OSTCOUNT )); then
7029                 echo -n "Migrating 1GB file..."
7030                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7031                         error "cannot migrate 1GB file"
7032                 echo "done"
7033                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7034                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7035                         error "cannot getstripe for 1GB file"
7036                 [ $stripe_count -eq 2 ] ||
7037                         error "unexpected stripe count $stripe_count != 2"
7038                 echo "done"
7039         fi
7040
7041         # Test 3: File is too large to fit within the available space on
7042         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7043         if [ $OSTCOUNT -ge 3 ]; then
7044                 # The required available space is calculated as
7045                 # file size (1GB + 3KB) / OST count (3).
7046                 local kb_per_ost=349526
7047
7048                 echo -n "Migrating 1GB file with limit..."
7049                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7050                         error "cannot migrate 1GB file with limit"
7051                 echo "done"
7052
7053                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7054                 echo -n "Verifying 1GB autostripe count with limited space..."
7055                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7056                         error "unexpected stripe count $stripe_count (min 3)"
7057                 echo "done"
7058         fi
7059
7060         # clean up
7061         rm -rf $dir
7062 }
7063 run_test 56xc "lfs migration autostripe"
7064
7065 test_56xd() {
7066         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7067
7068         local dir=$DIR/$tdir
7069         local f_mgrt=$dir/$tfile.mgrt
7070         local f_yaml=$dir/$tfile.yaml
7071         local f_copy=$dir/$tfile.copy
7072         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7073         local layout_copy="-c 2 -S 2M -i 1"
7074         local yamlfile=$dir/yamlfile
7075         local layout_before;
7076         local layout_after;
7077
7078         test_mkdir "$dir" || error "cannot create dir $dir"
7079         $LFS setstripe $layout_yaml $f_yaml ||
7080                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7081         $LFS getstripe --yaml $f_yaml > $yamlfile
7082         $LFS setstripe $layout_copy $f_copy ||
7083                 error "cannot setstripe $f_copy with layout $layout_copy"
7084         touch $f_mgrt
7085         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7086
7087         # 1. test option --yaml
7088         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7089                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7090         layout_before=$(get_layout_param $f_yaml)
7091         layout_after=$(get_layout_param $f_mgrt)
7092         [ "$layout_after" == "$layout_before" ] ||
7093                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7094
7095         # 2. test option --copy
7096         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7097                 error "cannot migrate $f_mgrt with --copy $f_copy"
7098         layout_before=$(get_layout_param $f_copy)
7099         layout_after=$(get_layout_param $f_mgrt)
7100         [ "$layout_after" == "$layout_before" ] ||
7101                 error "lfs_migrate --copy: $layout_after != $layout_before"
7102 }
7103 run_test 56xd "check lfs_migrate --yaml and --copy support"
7104
7105 test_56xe() {
7106         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7107
7108         local dir=$DIR/$tdir
7109         local f_comp=$dir/$tfile
7110         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7111         local layout_before=""
7112         local layout_after=""
7113
7114         test_mkdir "$dir" || error "cannot create dir $dir"
7115         $LFS setstripe $layout $f_comp ||
7116                 error "cannot setstripe $f_comp with layout $layout"
7117         layout_before=$(get_layout_param $f_comp)
7118         dd if=/dev/zero of=$f_comp bs=1M count=4
7119
7120         # 1. migrate a comp layout file by lfs_migrate
7121         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7122         layout_after=$(get_layout_param $f_comp)
7123         [ "$layout_before" == "$layout_after" ] ||
7124                 error "lfs_migrate: $layout_before != $layout_after"
7125
7126         # 2. migrate a comp layout file by lfs migrate
7127         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7128         layout_after=$(get_layout_param $f_comp)
7129         [ "$layout_before" == "$layout_after" ] ||
7130                 error "lfs migrate: $layout_before != $layout_after"
7131 }
7132 run_test 56xe "migrate a composite layout file"
7133
7134 test_56xf() {
7135         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7136
7137         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7138                 skip "Need server version at least 2.13.53"
7139
7140         local dir=$DIR/$tdir
7141         local f_comp=$dir/$tfile
7142         local layout="-E 1M -c1 -E -1 -c2"
7143         local fid_before=""
7144         local fid_after=""
7145
7146         test_mkdir "$dir" || error "cannot create dir $dir"
7147         $LFS setstripe $layout $f_comp ||
7148                 error "cannot setstripe $f_comp with layout $layout"
7149         fid_before=$($LFS getstripe --fid $f_comp)
7150         dd if=/dev/zero of=$f_comp bs=1M count=4
7151
7152         # 1. migrate a comp layout file to a comp layout
7153         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7154         fid_after=$($LFS getstripe --fid $f_comp)
7155         [ "$fid_before" == "$fid_after" ] ||
7156                 error "comp-to-comp migrate: $fid_before != $fid_after"
7157
7158         # 2. migrate a comp layout file to a plain layout
7159         $LFS migrate -c2 $f_comp ||
7160                 error "cannot migrate $f_comp by lfs migrate"
7161         fid_after=$($LFS getstripe --fid $f_comp)
7162         [ "$fid_before" == "$fid_after" ] ||
7163                 error "comp-to-plain migrate: $fid_before != $fid_after"
7164
7165         # 3. migrate a plain layout file to a comp layout
7166         $LFS migrate $layout $f_comp ||
7167                 error "cannot migrate $f_comp by lfs migrate"
7168         fid_after=$($LFS getstripe --fid $f_comp)
7169         [ "$fid_before" == "$fid_after" ] ||
7170                 error "plain-to-comp migrate: $fid_before != $fid_after"
7171 }
7172 run_test 56xf "FID is not lost during migration of a composite layout file"
7173
7174 test_56y() {
7175         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7176                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7177
7178         local res=""
7179         local dir=$DIR/$tdir
7180         local f1=$dir/file1
7181         local f2=$dir/file2
7182
7183         test_mkdir -p $dir || error "creating dir $dir"
7184         touch $f1 || error "creating std file $f1"
7185         $MULTIOP $f2 H2c || error "creating released file $f2"
7186
7187         # a directory can be raid0, so ask only for files
7188         res=$($LFS find $dir -L raid0 -type f | wc -l)
7189         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7190
7191         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7192         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7193
7194         # only files can be released, so no need to force file search
7195         res=$($LFS find $dir -L released)
7196         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7197
7198         res=$($LFS find $dir -type f \! -L released)
7199         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7200 }
7201 run_test 56y "lfs find -L raid0|released"
7202
7203 test_56z() { # LU-4824
7204         # This checks to make sure 'lfs find' continues after errors
7205         # There are two classes of errors that should be caught:
7206         # - If multiple paths are provided, all should be searched even if one
7207         #   errors out
7208         # - If errors are encountered during the search, it should not terminate
7209         #   early
7210         local dir=$DIR/$tdir
7211         local i
7212
7213         test_mkdir $dir
7214         for i in d{0..9}; do
7215                 test_mkdir $dir/$i
7216                 touch $dir/$i/$tfile
7217         done
7218         $LFS find $DIR/non_existent_dir $dir &&
7219                 error "$LFS find did not return an error"
7220         # Make a directory unsearchable. This should NOT be the last entry in
7221         # directory order.  Arbitrarily pick the 6th entry
7222         chmod 700 $($LFS find $dir -type d | sed '6!d')
7223
7224         $RUNAS $LFS find $DIR/non_existent $dir
7225         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7226
7227         # The user should be able to see 10 directories and 9 files
7228         (( count == 19 )) ||
7229                 error "$LFS find found $count != 19 entries after error"
7230 }
7231 run_test 56z "lfs find should continue after an error"
7232
7233 test_56aa() { # LU-5937
7234         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7235
7236         local dir=$DIR/$tdir
7237
7238         mkdir $dir
7239         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7240
7241         createmany -o $dir/striped_dir/${tfile}- 1024
7242         local dirs=$($LFS find --size +8k $dir/)
7243
7244         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7245 }
7246 run_test 56aa "lfs find --size under striped dir"
7247
7248 test_56ab() { # LU-10705
7249         test_mkdir $DIR/$tdir
7250         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7251         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7252         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7253         # Flush writes to ensure valid blocks.  Need to be more thorough for
7254         # ZFS, since blocks are not allocated/returned to client immediately.
7255         sync_all_data
7256         wait_zfs_commit ost1 2
7257         cancel_lru_locks osc
7258         ls -ls $DIR/$tdir
7259
7260         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7261
7262         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7263
7264         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7265         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7266
7267         rm -f $DIR/$tdir/$tfile.[123]
7268 }
7269 run_test 56ab "lfs find --blocks"
7270
7271 test_56ba() {
7272         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7273                 skip "Need MDS version at least 2.10.50"
7274
7275         # Create composite files with one component
7276         local dir=$DIR/$tdir
7277
7278         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7279         # Create composite files with three components
7280         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7281         # Create non-composite files
7282         createmany -o $dir/${tfile}- 10
7283
7284         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7285
7286         [[ $nfiles == 10 ]] ||
7287                 error "lfs find -E 1M found $nfiles != 10 files"
7288
7289         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7290         [[ $nfiles == 25 ]] ||
7291                 error "lfs find ! -E 1M found $nfiles != 25 files"
7292
7293         # All files have a component that starts at 0
7294         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7295         [[ $nfiles == 35 ]] ||
7296                 error "lfs find --component-start 0 - $nfiles != 35 files"
7297
7298         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7299         [[ $nfiles == 15 ]] ||
7300                 error "lfs find --component-start 2M - $nfiles != 15 files"
7301
7302         # All files created here have a componenet that does not starts at 2M
7303         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7304         [[ $nfiles == 35 ]] ||
7305                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7306
7307         # Find files with a specified number of components
7308         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7309         [[ $nfiles == 15 ]] ||
7310                 error "lfs find --component-count 3 - $nfiles != 15 files"
7311
7312         # Remember non-composite files have a component count of zero
7313         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7314         [[ $nfiles == 10 ]] ||
7315                 error "lfs find --component-count 0 - $nfiles != 10 files"
7316
7317         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7318         [[ $nfiles == 20 ]] ||
7319                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7320
7321         # All files have a flag called "init"
7322         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7323         [[ $nfiles == 35 ]] ||
7324                 error "lfs find --component-flags init - $nfiles != 35 files"
7325
7326         # Multi-component files will have a component not initialized
7327         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7328         [[ $nfiles == 15 ]] ||
7329                 error "lfs find !--component-flags init - $nfiles != 15 files"
7330
7331         rm -rf $dir
7332
7333 }
7334 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7335
7336 test_56ca() {
7337         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7338                 skip "Need MDS version at least 2.10.57"
7339
7340         local td=$DIR/$tdir
7341         local tf=$td/$tfile
7342         local dir
7343         local nfiles
7344         local cmd
7345         local i
7346         local j
7347
7348         # create mirrored directories and mirrored files
7349         mkdir $td || error "mkdir $td failed"
7350         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7351         createmany -o $tf- 10 || error "create $tf- failed"
7352
7353         for i in $(seq 2); do
7354                 dir=$td/dir$i
7355                 mkdir $dir || error "mkdir $dir failed"
7356                 $LFS mirror create -N$((3 + i)) $dir ||
7357                         error "create mirrored dir $dir failed"
7358                 createmany -o $dir/$tfile- 10 ||
7359                         error "create $dir/$tfile- failed"
7360         done
7361
7362         # change the states of some mirrored files
7363         echo foo > $tf-6
7364         for i in $(seq 2); do
7365                 dir=$td/dir$i
7366                 for j in $(seq 4 9); do
7367                         echo foo > $dir/$tfile-$j
7368                 done
7369         done
7370
7371         # find mirrored files with specific mirror count
7372         cmd="$LFS find --mirror-count 3 --type f $td"
7373         nfiles=$($cmd | wc -l)
7374         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7375
7376         cmd="$LFS find ! --mirror-count 3 --type f $td"
7377         nfiles=$($cmd | wc -l)
7378         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7379
7380         cmd="$LFS find --mirror-count +2 --type f $td"
7381         nfiles=$($cmd | wc -l)
7382         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7383
7384         cmd="$LFS find --mirror-count -6 --type f $td"
7385         nfiles=$($cmd | wc -l)
7386         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7387
7388         # find mirrored files with specific file state
7389         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7390         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7391
7392         cmd="$LFS find --mirror-state=ro --type f $td"
7393         nfiles=$($cmd | wc -l)
7394         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7395
7396         cmd="$LFS find ! --mirror-state=ro --type f $td"
7397         nfiles=$($cmd | wc -l)
7398         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7399
7400         cmd="$LFS find --mirror-state=wp --type f $td"
7401         nfiles=$($cmd | wc -l)
7402         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7403
7404         cmd="$LFS find ! --mirror-state=sp --type f $td"
7405         nfiles=$($cmd | wc -l)
7406         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7407 }
7408 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7409
7410 test_57a() {
7411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7412         # note test will not do anything if MDS is not local
7413         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7414                 skip_env "ldiskfs only test"
7415         fi
7416         remote_mds_nodsh && skip "remote MDS with nodsh"
7417
7418         local MNTDEV="osd*.*MDT*.mntdev"
7419         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7420         [ -z "$DEV" ] && error "can't access $MNTDEV"
7421         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7422                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7423                         error "can't access $DEV"
7424                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7425                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7426                 rm $TMP/t57a.dump
7427         done
7428 }
7429 run_test 57a "verify MDS filesystem created with large inodes =="
7430
7431 test_57b() {
7432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7433         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7434                 skip_env "ldiskfs only test"
7435         fi
7436         remote_mds_nodsh && skip "remote MDS with nodsh"
7437
7438         local dir=$DIR/$tdir
7439         local filecount=100
7440         local file1=$dir/f1
7441         local fileN=$dir/f$filecount
7442
7443         rm -rf $dir || error "removing $dir"
7444         test_mkdir -c1 $dir
7445         local mdtidx=$($LFS getstripe -m $dir)
7446         local mdtname=MDT$(printf %04x $mdtidx)
7447         local facet=mds$((mdtidx + 1))
7448
7449         echo "mcreating $filecount files"
7450         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7451
7452         # verify that files do not have EAs yet
7453         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7454                 error "$file1 has an EA"
7455         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7456                 error "$fileN has an EA"
7457
7458         sync
7459         sleep 1
7460         df $dir  #make sure we get new statfs data
7461         local mdsfree=$(do_facet $facet \
7462                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7463         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7464         local file
7465
7466         echo "opening files to create objects/EAs"
7467         for file in $(seq -f $dir/f%g 1 $filecount); do
7468                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7469                         error "opening $file"
7470         done
7471
7472         # verify that files have EAs now
7473         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7474         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7475
7476         sleep 1  #make sure we get new statfs data
7477         df $dir
7478         local mdsfree2=$(do_facet $facet \
7479                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7480         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7481
7482         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7483                 if [ "$mdsfree" != "$mdsfree2" ]; then
7484                         error "MDC before $mdcfree != after $mdcfree2"
7485                 else
7486                         echo "MDC before $mdcfree != after $mdcfree2"
7487                         echo "unable to confirm if MDS has large inodes"
7488                 fi
7489         fi
7490         rm -rf $dir
7491 }
7492 run_test 57b "default LOV EAs are stored inside large inodes ==="
7493
7494 test_58() {
7495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7496         [ -z "$(which wiretest 2>/dev/null)" ] &&
7497                         skip_env "could not find wiretest"
7498
7499         wiretest
7500 }
7501 run_test 58 "verify cross-platform wire constants =============="
7502
7503 test_59() {
7504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7505
7506         echo "touch 130 files"
7507         createmany -o $DIR/f59- 130
7508         echo "rm 130 files"
7509         unlinkmany $DIR/f59- 130
7510         sync
7511         # wait for commitment of removal
7512         wait_delete_completed
7513 }
7514 run_test 59 "verify cancellation of llog records async ========="
7515
7516 TEST60_HEAD="test_60 run $RANDOM"
7517 test_60a() {
7518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7519         remote_mgs_nodsh && skip "remote MGS with nodsh"
7520         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7521                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7522                         skip_env "missing subtest run-llog.sh"
7523
7524         log "$TEST60_HEAD - from kernel mode"
7525         do_facet mgs "$LCTL dk > /dev/null"
7526         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7527         do_facet mgs $LCTL dk > $TMP/$tfile
7528
7529         # LU-6388: test llog_reader
7530         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7531         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7532         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7533                         skip_env "missing llog_reader"
7534         local fstype=$(facet_fstype mgs)
7535         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7536                 skip_env "Only for ldiskfs or zfs type mgs"
7537
7538         local mntpt=$(facet_mntpt mgs)
7539         local mgsdev=$(mgsdevname 1)
7540         local fid_list
7541         local fid
7542         local rec_list
7543         local rec
7544         local rec_type
7545         local obj_file
7546         local path
7547         local seq
7548         local oid
7549         local pass=true
7550
7551         #get fid and record list
7552         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7553                 tail -n 4))
7554         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7555                 tail -n 4))
7556         #remount mgs as ldiskfs or zfs type
7557         stop mgs || error "stop mgs failed"
7558         mount_fstype mgs || error "remount mgs failed"
7559         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7560                 fid=${fid_list[i]}
7561                 rec=${rec_list[i]}
7562                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7563                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7564                 oid=$((16#$oid))
7565
7566                 case $fstype in
7567                         ldiskfs )
7568                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7569                         zfs )
7570                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7571                 esac
7572                 echo "obj_file is $obj_file"
7573                 do_facet mgs $llog_reader $obj_file
7574
7575                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7576                         awk '{ print $3 }' | sed -e "s/^type=//g")
7577                 if [ $rec_type != $rec ]; then
7578                         echo "FAILED test_60a wrong record type $rec_type," \
7579                               "should be $rec"
7580                         pass=false
7581                         break
7582                 fi
7583
7584                 #check obj path if record type is LLOG_LOGID_MAGIC
7585                 if [ "$rec" == "1064553b" ]; then
7586                         path=$(do_facet mgs $llog_reader $obj_file |
7587                                 grep "path=" | awk '{ print $NF }' |
7588                                 sed -e "s/^path=//g")
7589                         if [ $obj_file != $mntpt/$path ]; then
7590                                 echo "FAILED test_60a wrong obj path" \
7591                                       "$montpt/$path, should be $obj_file"
7592                                 pass=false
7593                                 break
7594                         fi
7595                 fi
7596         done
7597         rm -f $TMP/$tfile
7598         #restart mgs before "error", otherwise it will block the next test
7599         stop mgs || error "stop mgs failed"
7600         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7601         $pass || error "test failed, see FAILED test_60a messages for specifics"
7602 }
7603 run_test 60a "llog_test run from kernel module and test llog_reader"
7604
7605 test_60b() { # bug 6411
7606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7607
7608         dmesg > $DIR/$tfile
7609         LLOG_COUNT=$(do_facet mgs dmesg |
7610                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7611                           /llog_[a-z]*.c:[0-9]/ {
7612                                 if (marker)
7613                                         from_marker++
7614                                 from_begin++
7615                           }
7616                           END {
7617                                 if (marker)
7618                                         print from_marker
7619                                 else
7620                                         print from_begin
7621                           }")
7622
7623         [[ $LLOG_COUNT -gt 120 ]] &&
7624                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7625 }
7626 run_test 60b "limit repeated messages from CERROR/CWARN"
7627
7628 test_60c() {
7629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7630
7631         echo "create 5000 files"
7632         createmany -o $DIR/f60c- 5000
7633 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7634         lctl set_param fail_loc=0x80000137
7635         unlinkmany $DIR/f60c- 5000
7636         lctl set_param fail_loc=0
7637 }
7638 run_test 60c "unlink file when mds full"
7639
7640 test_60d() {
7641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7642
7643         SAVEPRINTK=$(lctl get_param -n printk)
7644         # verify "lctl mark" is even working"
7645         MESSAGE="test message ID $RANDOM $$"
7646         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7647         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7648
7649         lctl set_param printk=0 || error "set lnet.printk failed"
7650         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7651         MESSAGE="new test message ID $RANDOM $$"
7652         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7653         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7654         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7655
7656         lctl set_param -n printk="$SAVEPRINTK"
7657 }
7658 run_test 60d "test printk console message masking"
7659
7660 test_60e() {
7661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7662         remote_mds_nodsh && skip "remote MDS with nodsh"
7663
7664         touch $DIR/$tfile
7665 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7666         do_facet mds1 lctl set_param fail_loc=0x15b
7667         rm $DIR/$tfile
7668 }
7669 run_test 60e "no space while new llog is being created"
7670
7671 test_60g() {
7672         local pid
7673         local i
7674
7675         test_mkdir -c $MDSCOUNT $DIR/$tdir
7676
7677         (
7678                 local index=0
7679                 while true; do
7680                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7681                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7682                                 2>/dev/null
7683                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7684                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7685                         index=$((index + 1))
7686                 done
7687         ) &
7688
7689         pid=$!
7690
7691         for i in {0..100}; do
7692                 # define OBD_FAIL_OSD_TXN_START    0x19a
7693                 local index=$((i % MDSCOUNT + 1))
7694
7695                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7696                         > /dev/null
7697                 usleep 100
7698         done
7699
7700         kill -9 $pid
7701
7702         for i in $(seq $MDSCOUNT); do
7703                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7704         done
7705
7706         mkdir $DIR/$tdir/new || error "mkdir failed"
7707         rmdir $DIR/$tdir/new || error "rmdir failed"
7708
7709         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7710                 -t namespace
7711         for i in $(seq $MDSCOUNT); do
7712                 wait_update_facet mds$i "$LCTL get_param -n \
7713                         mdd.$(facet_svc mds$i).lfsck_namespace |
7714                         awk '/^status/ { print \\\$2 }'" "completed"
7715         done
7716
7717         ls -R $DIR/$tdir || error "ls failed"
7718         rm -rf $DIR/$tdir || error "rmdir failed"
7719 }
7720 run_test 60g "transaction abort won't cause MDT hung"
7721
7722 test_60h() {
7723         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7724                 skip "Need MDS version at least 2.12.52"
7725         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7726
7727         local f
7728
7729         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7730         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7731         for fail_loc in 0x80000188 0x80000189; do
7732                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7733                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7734                         error "mkdir $dir-$fail_loc failed"
7735                 for i in {0..10}; do
7736                         # create may fail on missing stripe
7737                         echo $i > $DIR/$tdir-$fail_loc/$i
7738                 done
7739                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7740                         error "getdirstripe $tdir-$fail_loc failed"
7741                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7742                         error "migrate $tdir-$fail_loc failed"
7743                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7744                         error "getdirstripe $tdir-$fail_loc failed"
7745                 pushd $DIR/$tdir-$fail_loc
7746                 for f in *; do
7747                         echo $f | cmp $f - || error "$f data mismatch"
7748                 done
7749                 popd
7750                 rm -rf $DIR/$tdir-$fail_loc
7751         done
7752 }
7753 run_test 60h "striped directory with missing stripes can be accessed"
7754
7755 test_61a() {
7756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7757
7758         f="$DIR/f61"
7759         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7760         cancel_lru_locks osc
7761         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7762         sync
7763 }
7764 run_test 61a "mmap() writes don't make sync hang ================"
7765
7766 test_61b() {
7767         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7768 }
7769 run_test 61b "mmap() of unstriped file is successful"
7770
7771 # bug 2330 - insufficient obd_match error checking causes LBUG
7772 test_62() {
7773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7774
7775         f="$DIR/f62"
7776         echo foo > $f
7777         cancel_lru_locks osc
7778         lctl set_param fail_loc=0x405
7779         cat $f && error "cat succeeded, expect -EIO"
7780         lctl set_param fail_loc=0
7781 }
7782 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7783 # match every page all of the time.
7784 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7785
7786 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7787 # Though this test is irrelevant anymore, it helped to reveal some
7788 # other grant bugs (LU-4482), let's keep it.
7789 test_63a() {   # was test_63
7790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7791
7792         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7793
7794         for i in `seq 10` ; do
7795                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7796                 sleep 5
7797                 kill $!
7798                 sleep 1
7799         done
7800
7801         rm -f $DIR/f63 || true
7802 }
7803 run_test 63a "Verify oig_wait interruption does not crash ======="
7804
7805 # bug 2248 - async write errors didn't return to application on sync
7806 # bug 3677 - async write errors left page locked
7807 test_63b() {
7808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7809
7810         debugsave
7811         lctl set_param debug=-1
7812
7813         # ensure we have a grant to do async writes
7814         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7815         rm $DIR/$tfile
7816
7817         sync    # sync lest earlier test intercept the fail_loc
7818
7819         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7820         lctl set_param fail_loc=0x80000406
7821         $MULTIOP $DIR/$tfile Owy && \
7822                 error "sync didn't return ENOMEM"
7823         sync; sleep 2; sync     # do a real sync this time to flush page
7824         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7825                 error "locked page left in cache after async error" || true
7826         debugrestore
7827 }
7828 run_test 63b "async write errors should be returned to fsync ==="
7829
7830 test_64a () {
7831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7832
7833         lfs df $DIR
7834         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
7835 }
7836 run_test 64a "verify filter grant calculations (in kernel) ====="
7837
7838 test_64b () {
7839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7840
7841         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7842 }
7843 run_test 64b "check out-of-space detection on client"
7844
7845 test_64c() {
7846         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7847 }
7848 run_test 64c "verify grant shrink"
7849
7850 import_param() {
7851         local tgt=$1
7852         local param=$2
7853
7854         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
7855 }
7856
7857 # this does exactly what osc_request.c:osc_announce_cached() does in
7858 # order to calculate max amount of grants to ask from server
7859 want_grant() {
7860         local tgt=$1
7861
7862         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
7863         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
7864
7865         ((rpc_in_flight++));
7866         nrpages=$((nrpages * rpc_in_flight))
7867
7868         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
7869
7870         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7871
7872         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7873         local undirty=$((nrpages * PAGE_SIZE))
7874
7875         local max_extent_pages
7876         max_extent_pages=$(import_param $tgt grant_max_extent_size)
7877         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7878         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7879         local grant_extent_tax
7880         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7881
7882         undirty=$((undirty + nrextents * grant_extent_tax))
7883
7884         echo $undirty
7885 }
7886
7887 # this is size of unit for grant allocation. It should be equal to
7888 # what tgt_grant.c:tgt_grant_chunk() calculates
7889 grant_chunk() {
7890         local tgt=$1
7891         local max_brw_size
7892         local grant_extent_tax
7893
7894         max_brw_size=$(import_param $tgt max_brw_size)
7895
7896         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7897
7898         echo $(((max_brw_size + grant_extent_tax) * 2))
7899 }
7900
7901 test_64d() {
7902         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
7903                 skip "OST < 2.10.55 doesn't limit grants enough"
7904
7905         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
7906
7907         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
7908                 skip "no grant_param connect flag"
7909
7910         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
7911
7912         $LCTL set_param -n -n debug="$OLDDEBUG" || true
7913         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
7914
7915
7916         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7917         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
7918
7919         $LFS setstripe $DIR/$tfile -i 0 -c 1
7920         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
7921         ddpid=$!
7922
7923         while kill -0 $ddpid; do
7924                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7925
7926                 if [[ $cur_grant -gt $max_cur_granted ]]; then
7927                         kill $ddpid
7928                         error "cur_grant $cur_grant > $max_cur_granted"
7929                 fi
7930
7931                 sleep 1
7932         done
7933 }
7934 run_test 64d "check grant limit exceed"
7935
7936 check_grants() {
7937         local tgt=$1
7938         local expected=$2
7939         local msg=$3
7940         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7941
7942         ((cur_grants == expected)) ||
7943                 error "$msg: grants mismatch: $cur_grants, expected $expected"
7944 }
7945
7946 round_up_p2() {
7947         echo $((($1 + $2 - 1) & ~($2 - 1)))
7948 }
7949
7950 test_64e() {
7951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7952         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
7953                 skip "Need OSS version at least 2.11.56"
7954
7955         # Remount client to reset grant
7956         remount_client $MOUNT || error "failed to remount client"
7957         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
7958
7959         local init_grants=$(import_param $osc_tgt initial_grant)
7960
7961         check_grants $osc_tgt $init_grants "init grants"
7962
7963         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
7964         local max_brw_size=$(import_param $osc_tgt max_brw_size)
7965         local gbs=$(import_param $osc_tgt grant_block_size)
7966
7967         # write random number of bytes from max_brw_size / 4 to max_brw_size
7968         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
7969         # align for direct io
7970         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
7971         # round to grant consumption unit
7972         local wb_round_up=$(round_up_p2 $write_bytes gbs)
7973
7974         local grants=$((wb_round_up + extent_tax))
7975
7976         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
7977
7978         # define OBD_FAIL_TGT_NO_GRANT 0x725
7979         # make the server not grant more back
7980         do_facet ost1 $LCTL set_param fail_loc=0x725
7981         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
7982
7983         do_facet ost1 $LCTL set_param fail_loc=0
7984
7985         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
7986
7987         rm -f $DIR/$tfile || error "rm failed"
7988
7989         # Remount client to reset grant
7990         remount_client $MOUNT || error "failed to remount client"
7991         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
7992
7993         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
7994
7995         # define OBD_FAIL_TGT_NO_GRANT 0x725
7996         # make the server not grant more back
7997         do_facet ost1 $LCTL set_param fail_loc=0x725
7998         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
7999         do_facet ost1 $LCTL set_param fail_loc=0
8000
8001         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8002 }
8003 run_test 64e "check grant consumption (no grant allocation)"
8004
8005 test_64f() {
8006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8007
8008         # Remount client to reset grant
8009         remount_client $MOUNT || error "failed to remount client"
8010         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8011
8012         local init_grants=$(import_param $osc_tgt initial_grant)
8013         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8014         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8015         local gbs=$(import_param $osc_tgt grant_block_size)
8016         local chunk=$(grant_chunk $osc_tgt)
8017
8018         # write random number of bytes from max_brw_size / 4 to max_brw_size
8019         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8020         # align for direct io
8021         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8022         # round to grant consumption unit
8023         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8024
8025         local grants=$((wb_round_up + extent_tax))
8026
8027         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8028         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8029                 error "error writing to $DIR/$tfile"
8030
8031         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8032                 "direct io with grant allocation"
8033
8034         rm -f $DIR/$tfile || error "rm failed"
8035
8036         # Remount client to reset grant
8037         remount_client $MOUNT || error "failed to remount client"
8038         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8039
8040         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8041
8042         local cmd="oO_WRONLY:w${write_bytes}_yc"
8043
8044         $MULTIOP $DIR/$tfile $cmd &
8045         MULTIPID=$!
8046         sleep 1
8047
8048         check_grants $osc_tgt $((init_grants - grants)) \
8049                 "buffered io, not write rpc"
8050
8051         kill -USR1 $MULTIPID
8052         wait
8053
8054         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8055                 "buffered io, one RPC"
8056 }
8057 run_test 64f "check grant consumption (with grant allocation)"
8058
8059 # bug 1414 - set/get directories' stripe info
8060 test_65a() {
8061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8062
8063         test_mkdir $DIR/$tdir
8064         touch $DIR/$tdir/f1
8065         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8066 }
8067 run_test 65a "directory with no stripe info"
8068
8069 test_65b() {
8070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8071
8072         test_mkdir $DIR/$tdir
8073         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8074
8075         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8076                                                 error "setstripe"
8077         touch $DIR/$tdir/f2
8078         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8079 }
8080 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8081
8082 test_65c() {
8083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8084         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8085
8086         test_mkdir $DIR/$tdir
8087         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8088
8089         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8090                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8091         touch $DIR/$tdir/f3
8092         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8093 }
8094 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8095
8096 test_65d() {
8097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8098
8099         test_mkdir $DIR/$tdir
8100         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8101         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8102
8103         if [[ $STRIPECOUNT -le 0 ]]; then
8104                 sc=1
8105         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8106                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8107                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8108         else
8109                 sc=$(($STRIPECOUNT - 1))
8110         fi
8111         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8112         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8113         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8114                 error "lverify failed"
8115 }
8116 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8117
8118 test_65e() {
8119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8120
8121         test_mkdir $DIR/$tdir
8122
8123         $LFS setstripe $DIR/$tdir || error "setstripe"
8124         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8125                                         error "no stripe info failed"
8126         touch $DIR/$tdir/f6
8127         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8128 }
8129 run_test 65e "directory setstripe defaults"
8130
8131 test_65f() {
8132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8133
8134         test_mkdir $DIR/${tdir}f
8135         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8136                 error "setstripe succeeded" || true
8137 }
8138 run_test 65f "dir setstripe permission (should return error) ==="
8139
8140 test_65g() {
8141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8142
8143         test_mkdir $DIR/$tdir
8144         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8145
8146         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8147                 error "setstripe -S failed"
8148         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8149         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8150                 error "delete default stripe failed"
8151 }
8152 run_test 65g "directory setstripe -d"
8153
8154 test_65h() {
8155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8156
8157         test_mkdir $DIR/$tdir
8158         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8159
8160         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8161                 error "setstripe -S failed"
8162         test_mkdir $DIR/$tdir/dd1
8163         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8164                 error "stripe info inherit failed"
8165 }
8166 run_test 65h "directory stripe info inherit ===================="
8167
8168 test_65i() {
8169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8170
8171         save_layout_restore_at_exit $MOUNT
8172
8173         # bug6367: set non-default striping on root directory
8174         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8175
8176         # bug12836: getstripe on -1 default directory striping
8177         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8178
8179         # bug12836: getstripe -v on -1 default directory striping
8180         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8181
8182         # bug12836: new find on -1 default directory striping
8183         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8184 }
8185 run_test 65i "various tests to set root directory striping"
8186
8187 test_65j() { # bug6367
8188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8189
8190         sync; sleep 1
8191
8192         # if we aren't already remounting for each test, do so for this test
8193         if [ "$I_MOUNTED" = "yes" ]; then
8194                 cleanup || error "failed to unmount"
8195                 setup
8196         fi
8197
8198         save_layout_restore_at_exit $MOUNT
8199
8200         $LFS setstripe -d $MOUNT || error "setstripe failed"
8201 }
8202 run_test 65j "set default striping on root directory (bug 6367)="
8203
8204 cleanup_65k() {
8205         rm -rf $DIR/$tdir
8206         wait_delete_completed
8207         do_facet $SINGLEMDS "lctl set_param -n \
8208                 osp.$ost*MDT0000.max_create_count=$max_count"
8209         do_facet $SINGLEMDS "lctl set_param -n \
8210                 osp.$ost*MDT0000.create_count=$count"
8211         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8212         echo $INACTIVE_OSC "is Activate"
8213
8214         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8215 }
8216
8217 test_65k() { # bug11679
8218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8219         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8220         remote_mds_nodsh && skip "remote MDS with nodsh"
8221
8222         local disable_precreate=true
8223         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8224                 disable_precreate=false
8225
8226         echo "Check OST status: "
8227         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8228                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8229
8230         for OSC in $MDS_OSCS; do
8231                 echo $OSC "is active"
8232                 do_facet $SINGLEMDS lctl --device %$OSC activate
8233         done
8234
8235         for INACTIVE_OSC in $MDS_OSCS; do
8236                 local ost=$(osc_to_ost $INACTIVE_OSC)
8237                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8238                                lov.*md*.target_obd |
8239                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8240
8241                 mkdir -p $DIR/$tdir
8242                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8243                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8244
8245                 echo "Deactivate: " $INACTIVE_OSC
8246                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8247
8248                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8249                               osp.$ost*MDT0000.create_count")
8250                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8251                                   osp.$ost*MDT0000.max_create_count")
8252                 $disable_precreate &&
8253                         do_facet $SINGLEMDS "lctl set_param -n \
8254                                 osp.$ost*MDT0000.max_create_count=0"
8255
8256                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8257                         [ -f $DIR/$tdir/$idx ] && continue
8258                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8259                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8260                                 { cleanup_65k;
8261                                   error "setstripe $idx should succeed"; }
8262                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8263                 done
8264                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8265                 rmdir $DIR/$tdir
8266
8267                 do_facet $SINGLEMDS "lctl set_param -n \
8268                         osp.$ost*MDT0000.max_create_count=$max_count"
8269                 do_facet $SINGLEMDS "lctl set_param -n \
8270                         osp.$ost*MDT0000.create_count=$count"
8271                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8272                 echo $INACTIVE_OSC "is Activate"
8273
8274                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8275         done
8276 }
8277 run_test 65k "validate manual striping works properly with deactivated OSCs"
8278
8279 test_65l() { # bug 12836
8280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8281
8282         test_mkdir -p $DIR/$tdir/test_dir
8283         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8284         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8285 }
8286 run_test 65l "lfs find on -1 stripe dir ========================"
8287
8288 test_65m() {
8289         local layout=$(save_layout $MOUNT)
8290         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8291                 restore_layout $MOUNT $layout
8292                 error "setstripe should fail by non-root users"
8293         }
8294         true
8295 }
8296 run_test 65m "normal user can't set filesystem default stripe"
8297
8298 test_65n() {
8299         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8300         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8301                 skip "Need MDS version at least 2.12.50"
8302         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8303
8304         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8305         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8306         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8307
8308         local root_layout=$(save_layout $MOUNT)
8309         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8310
8311         # new subdirectory under root directory should not inherit
8312         # the default layout from root
8313         local dir1=$MOUNT/$tdir-1
8314         mkdir $dir1 || error "mkdir $dir1 failed"
8315         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8316                 error "$dir1 shouldn't have LOV EA"
8317
8318         # delete the default layout on root directory
8319         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8320
8321         local dir2=$MOUNT/$tdir-2
8322         mkdir $dir2 || error "mkdir $dir2 failed"
8323         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8324                 error "$dir2 shouldn't have LOV EA"
8325
8326         # set a new striping pattern on root directory
8327         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8328         local new_def_stripe_size=$((def_stripe_size * 2))
8329         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8330                 error "set stripe size on $MOUNT failed"
8331
8332         # new file created in $dir2 should inherit the new stripe size from
8333         # the filesystem default
8334         local file2=$dir2/$tfile-2
8335         touch $file2 || error "touch $file2 failed"
8336
8337         local file2_stripe_size=$($LFS getstripe -S $file2)
8338         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8339                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8340
8341         local dir3=$MOUNT/$tdir-3
8342         mkdir $dir3 || error "mkdir $dir3 failed"
8343         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8344         # the root layout, which is the actual default layout that will be used
8345         # when new files are created in $dir3.
8346         local dir3_layout=$(get_layout_param $dir3)
8347         local root_dir_layout=$(get_layout_param $MOUNT)
8348         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8349                 error "$dir3 should show the default layout from $MOUNT"
8350
8351         # set OST pool on root directory
8352         local pool=$TESTNAME
8353         pool_add $pool || error "add $pool failed"
8354         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8355                 error "add targets to $pool failed"
8356
8357         $LFS setstripe -p $pool $MOUNT ||
8358                 error "set OST pool on $MOUNT failed"
8359
8360         # new file created in $dir3 should inherit the pool from
8361         # the filesystem default
8362         local file3=$dir3/$tfile-3
8363         touch $file3 || error "touch $file3 failed"
8364
8365         local file3_pool=$($LFS getstripe -p $file3)
8366         [[ "$file3_pool" = "$pool" ]] ||
8367                 error "$file3 didn't inherit OST pool $pool"
8368
8369         local dir4=$MOUNT/$tdir-4
8370         mkdir $dir4 || error "mkdir $dir4 failed"
8371         local dir4_layout=$(get_layout_param $dir4)
8372         root_dir_layout=$(get_layout_param $MOUNT)
8373         echo "$LFS getstripe -d $dir4"
8374         $LFS getstripe -d $dir4
8375         echo "$LFS getstripe -d $MOUNT"
8376         $LFS getstripe -d $MOUNT
8377         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8378                 error "$dir4 should show the default layout from $MOUNT"
8379
8380         # new file created in $dir4 should inherit the pool from
8381         # the filesystem default
8382         local file4=$dir4/$tfile-4
8383         touch $file4 || error "touch $file4 failed"
8384
8385         local file4_pool=$($LFS getstripe -p $file4)
8386         [[ "$file4_pool" = "$pool" ]] ||
8387                 error "$file4 didn't inherit OST pool $pool"
8388
8389         # new subdirectory under non-root directory should inherit
8390         # the default layout from its parent directory
8391         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8392                 error "set directory layout on $dir4 failed"
8393
8394         local dir5=$dir4/$tdir-5
8395         mkdir $dir5 || error "mkdir $dir5 failed"
8396
8397         dir4_layout=$(get_layout_param $dir4)
8398         local dir5_layout=$(get_layout_param $dir5)
8399         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8400                 error "$dir5 should inherit the default layout from $dir4"
8401
8402         # though subdir under ROOT doesn't inherit default layout, but
8403         # its sub dir/file should be created with default layout.
8404         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8405         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8406                 skip "Need MDS version at least 2.12.59"
8407
8408         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8409         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8410         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8411
8412         if [ $default_lmv_hash == "none" ]; then
8413                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8414         else
8415                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8416                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8417         fi
8418
8419         $LFS setdirstripe -D -c 2 $MOUNT ||
8420                 error "setdirstripe -D -c 2 failed"
8421         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8422         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8423         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8424 }
8425 run_test 65n "don't inherit default layout from root for new subdirectories"
8426
8427 # bug 2543 - update blocks count on client
8428 test_66() {
8429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8430
8431         COUNT=${COUNT:-8}
8432         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8433         sync; sync_all_data; sync; sync_all_data
8434         cancel_lru_locks osc
8435         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8436         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8437 }
8438 run_test 66 "update inode blocks count on client ==============="
8439
8440 meminfo() {
8441         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8442 }
8443
8444 swap_used() {
8445         swapon -s | awk '($1 == "'$1'") { print $4 }'
8446 }
8447
8448 # bug5265, obdfilter oa2dentry return -ENOENT
8449 # #define OBD_FAIL_SRV_ENOENT 0x217
8450 test_69() {
8451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8452         remote_ost_nodsh && skip "remote OST with nodsh"
8453
8454         f="$DIR/$tfile"
8455         $LFS setstripe -c 1 -i 0 $f
8456
8457         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8458
8459         do_facet ost1 lctl set_param fail_loc=0x217
8460         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8461         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8462
8463         do_facet ost1 lctl set_param fail_loc=0
8464         $DIRECTIO write $f 0 2 || error "write error"
8465
8466         cancel_lru_locks osc
8467         $DIRECTIO read $f 0 1 || error "read error"
8468
8469         do_facet ost1 lctl set_param fail_loc=0x217
8470         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8471
8472         do_facet ost1 lctl set_param fail_loc=0
8473         rm -f $f
8474 }
8475 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8476
8477 test_71() {
8478         test_mkdir $DIR/$tdir
8479         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8480         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8481 }
8482 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8483
8484 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8486         [ "$RUNAS_ID" = "$UID" ] &&
8487                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8488         # Check that testing environment is properly set up. Skip if not
8489         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8490                 skip_env "User $RUNAS_ID does not exist - skipping"
8491
8492         touch $DIR/$tfile
8493         chmod 777 $DIR/$tfile
8494         chmod ug+s $DIR/$tfile
8495         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8496                 error "$RUNAS dd $DIR/$tfile failed"
8497         # See if we are still setuid/sgid
8498         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8499                 error "S/gid is not dropped on write"
8500         # Now test that MDS is updated too
8501         cancel_lru_locks mdc
8502         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8503                 error "S/gid is not dropped on MDS"
8504         rm -f $DIR/$tfile
8505 }
8506 run_test 72a "Test that remove suid works properly (bug5695) ===="
8507
8508 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8509         local perm
8510
8511         [ "$RUNAS_ID" = "$UID" ] &&
8512                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8513         [ "$RUNAS_ID" -eq 0 ] &&
8514                 skip_env "RUNAS_ID = 0 -- skipping"
8515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8516         # Check that testing environment is properly set up. Skip if not
8517         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8518                 skip_env "User $RUNAS_ID does not exist - skipping"
8519
8520         touch $DIR/${tfile}-f{g,u}
8521         test_mkdir $DIR/${tfile}-dg
8522         test_mkdir $DIR/${tfile}-du
8523         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8524         chmod g+s $DIR/${tfile}-{f,d}g
8525         chmod u+s $DIR/${tfile}-{f,d}u
8526         for perm in 777 2777 4777; do
8527                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8528                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8529                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8530                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8531         done
8532         true
8533 }
8534 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8535
8536 # bug 3462 - multiple simultaneous MDC requests
8537 test_73() {
8538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8539
8540         test_mkdir $DIR/d73-1
8541         test_mkdir $DIR/d73-2
8542         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8543         pid1=$!
8544
8545         lctl set_param fail_loc=0x80000129
8546         $MULTIOP $DIR/d73-1/f73-2 Oc &
8547         sleep 1
8548         lctl set_param fail_loc=0
8549
8550         $MULTIOP $DIR/d73-2/f73-3 Oc &
8551         pid3=$!
8552
8553         kill -USR1 $pid1
8554         wait $pid1 || return 1
8555
8556         sleep 25
8557
8558         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8559         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8560         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8561
8562         rm -rf $DIR/d73-*
8563 }
8564 run_test 73 "multiple MDC requests (should not deadlock)"
8565
8566 test_74a() { # bug 6149, 6184
8567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8568
8569         touch $DIR/f74a
8570         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8571         #
8572         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8573         # will spin in a tight reconnection loop
8574         $LCTL set_param fail_loc=0x8000030e
8575         # get any lock that won't be difficult - lookup works.
8576         ls $DIR/f74a
8577         $LCTL set_param fail_loc=0
8578         rm -f $DIR/f74a
8579         true
8580 }
8581 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8582
8583 test_74b() { # bug 13310
8584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8585
8586         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8587         #
8588         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8589         # will spin in a tight reconnection loop
8590         $LCTL set_param fail_loc=0x8000030e
8591         # get a "difficult" lock
8592         touch $DIR/f74b
8593         $LCTL set_param fail_loc=0
8594         rm -f $DIR/f74b
8595         true
8596 }
8597 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8598
8599 test_74c() {
8600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8601
8602         #define OBD_FAIL_LDLM_NEW_LOCK
8603         $LCTL set_param fail_loc=0x319
8604         touch $DIR/$tfile && error "touch successful"
8605         $LCTL set_param fail_loc=0
8606         true
8607 }
8608 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8609
8610 num_inodes() {
8611         [ -f /sys/kernel/slab/lustre_inode_cache/shrink ] &&
8612                 echo 1 > /sys/kernel/slab/lustre_inode_cache/shrink
8613         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
8614 }
8615
8616 test_76() { # Now for bug 20433, added originally in bug 1443
8617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8618
8619         cancel_lru_locks osc
8620         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8621         local before=$(num_inodes)
8622         local count=$((512 * cpus))
8623         [ "$SLOW" = "no" ] && count=$((64 * cpus))
8624
8625         echo "before inodes: $before"
8626         for i in $(seq $count); do
8627                 touch $DIR/$tfile
8628                 rm -f $DIR/$tfile
8629         done
8630         cancel_lru_locks osc
8631         local after=$(num_inodes)
8632         echo "after inodes: $after"
8633         while (( after > before + 8 * ${cpus:-1} )); do
8634                 sleep 1
8635                 after=$(num_inodes)
8636                 wait=$((wait + 1))
8637                 (( wait % 5 == 0 )) && echo "wait $wait seconds inodes: $after"
8638                 if (( wait > 30 )); then
8639                         error "inode slab grew from $before to $after"
8640                 fi
8641         done
8642 }
8643 run_test 76 "confirm clients recycle inodes properly ===="
8644
8645
8646 export ORIG_CSUM=""
8647 set_checksums()
8648 {
8649         # Note: in sptlrpc modes which enable its own bulk checksum, the
8650         # original crc32_le bulk checksum will be automatically disabled,
8651         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8652         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8653         # In this case set_checksums() will not be no-op, because sptlrpc
8654         # bulk checksum will be enabled all through the test.
8655
8656         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8657         lctl set_param -n osc.*.checksums $1
8658         return 0
8659 }
8660
8661 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8662                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8663 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8664                              tr -d [] | head -n1)}
8665 set_checksum_type()
8666 {
8667         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8668         rc=$?
8669         log "set checksum type to $1, rc = $rc"
8670         return $rc
8671 }
8672
8673 get_osc_checksum_type()
8674 {
8675         # arugment 1: OST name, like OST0000
8676         ost=$1
8677         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8678                         sed 's/.*\[\(.*\)\].*/\1/g')
8679         rc=$?
8680         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8681         echo $checksum_type
8682 }
8683
8684 F77_TMP=$TMP/f77-temp
8685 F77SZ=8
8686 setup_f77() {
8687         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8688                 error "error writing to $F77_TMP"
8689 }
8690
8691 test_77a() { # bug 10889
8692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8693         $GSS && skip_env "could not run with gss"
8694
8695         [ ! -f $F77_TMP ] && setup_f77
8696         set_checksums 1
8697         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8698         set_checksums 0
8699         rm -f $DIR/$tfile
8700 }
8701 run_test 77a "normal checksum read/write operation"
8702
8703 test_77b() { # bug 10889
8704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8705         $GSS && skip_env "could not run with gss"
8706
8707         [ ! -f $F77_TMP ] && setup_f77
8708         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8709         $LCTL set_param fail_loc=0x80000409
8710         set_checksums 1
8711
8712         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8713                 error "dd error: $?"
8714         $LCTL set_param fail_loc=0
8715
8716         for algo in $CKSUM_TYPES; do
8717                 cancel_lru_locks osc
8718                 set_checksum_type $algo
8719                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8720                 $LCTL set_param fail_loc=0x80000408
8721                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8722                 $LCTL set_param fail_loc=0
8723         done
8724         set_checksums 0
8725         set_checksum_type $ORIG_CSUM_TYPE
8726         rm -f $DIR/$tfile
8727 }
8728 run_test 77b "checksum error on client write, read"
8729
8730 cleanup_77c() {
8731         trap 0
8732         set_checksums 0
8733         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8734         $check_ost &&
8735                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8736         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8737         $check_ost && [ -n "$ost_file_prefix" ] &&
8738                 do_facet ost1 rm -f ${ost_file_prefix}\*
8739 }
8740
8741 test_77c() {
8742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8743         $GSS && skip_env "could not run with gss"
8744         remote_ost_nodsh && skip "remote OST with nodsh"
8745
8746         local bad1
8747         local osc_file_prefix
8748         local osc_file
8749         local check_ost=false
8750         local ost_file_prefix
8751         local ost_file
8752         local orig_cksum
8753         local dump_cksum
8754         local fid
8755
8756         # ensure corruption will occur on first OSS/OST
8757         $LFS setstripe -i 0 $DIR/$tfile
8758
8759         [ ! -f $F77_TMP ] && setup_f77
8760         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8761                 error "dd write error: $?"
8762         fid=$($LFS path2fid $DIR/$tfile)
8763
8764         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8765         then
8766                 check_ost=true
8767                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8768                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8769         else
8770                 echo "OSS do not support bulk pages dump upon error"
8771         fi
8772
8773         osc_file_prefix=$($LCTL get_param -n debug_path)
8774         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8775
8776         trap cleanup_77c EXIT
8777
8778         set_checksums 1
8779         # enable bulk pages dump upon error on Client
8780         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8781         # enable bulk pages dump upon error on OSS
8782         $check_ost &&
8783                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8784
8785         # flush Client cache to allow next read to reach OSS
8786         cancel_lru_locks osc
8787
8788         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8789         $LCTL set_param fail_loc=0x80000408
8790         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8791         $LCTL set_param fail_loc=0
8792
8793         rm -f $DIR/$tfile
8794
8795         # check cksum dump on Client
8796         osc_file=$(ls ${osc_file_prefix}*)
8797         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8798         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8799         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8800         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8801         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8802                      cksum)
8803         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8804         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8805                 error "dump content does not match on Client"
8806
8807         $check_ost || skip "No need to check cksum dump on OSS"
8808
8809         # check cksum dump on OSS
8810         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8811         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8812         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8813         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8814         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8815                 error "dump content does not match on OSS"
8816
8817         cleanup_77c
8818 }
8819 run_test 77c "checksum error on client read with debug"
8820
8821 test_77d() { # bug 10889
8822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8823         $GSS && skip_env "could not run with gss"
8824
8825         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8826         $LCTL set_param fail_loc=0x80000409
8827         set_checksums 1
8828         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8829                 error "direct write: rc=$?"
8830         $LCTL set_param fail_loc=0
8831         set_checksums 0
8832
8833         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8834         $LCTL set_param fail_loc=0x80000408
8835         set_checksums 1
8836         cancel_lru_locks osc
8837         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8838                 error "direct read: rc=$?"
8839         $LCTL set_param fail_loc=0
8840         set_checksums 0
8841 }
8842 run_test 77d "checksum error on OST direct write, read"
8843
8844 test_77f() { # bug 10889
8845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8846         $GSS && skip_env "could not run with gss"
8847
8848         set_checksums 1
8849         for algo in $CKSUM_TYPES; do
8850                 cancel_lru_locks osc
8851                 set_checksum_type $algo
8852                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8853                 $LCTL set_param fail_loc=0x409
8854                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8855                         error "direct write succeeded"
8856                 $LCTL set_param fail_loc=0
8857         done
8858         set_checksum_type $ORIG_CSUM_TYPE
8859         set_checksums 0
8860 }
8861 run_test 77f "repeat checksum error on write (expect error)"
8862
8863 test_77g() { # bug 10889
8864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8865         $GSS && skip_env "could not run with gss"
8866         remote_ost_nodsh && skip "remote OST with nodsh"
8867
8868         [ ! -f $F77_TMP ] && setup_f77
8869
8870         local file=$DIR/$tfile
8871         stack_trap "rm -f $file" EXIT
8872
8873         $LFS setstripe -c 1 -i 0 $file
8874         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8875         do_facet ost1 lctl set_param fail_loc=0x8000021a
8876         set_checksums 1
8877         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8878                 error "write error: rc=$?"
8879         do_facet ost1 lctl set_param fail_loc=0
8880         set_checksums 0
8881
8882         cancel_lru_locks osc
8883         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8884         do_facet ost1 lctl set_param fail_loc=0x8000021b
8885         set_checksums 1
8886         cmp $F77_TMP $file || error "file compare failed"
8887         do_facet ost1 lctl set_param fail_loc=0
8888         set_checksums 0
8889 }
8890 run_test 77g "checksum error on OST write, read"
8891
8892 test_77k() { # LU-10906
8893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8894         $GSS && skip_env "could not run with gss"
8895
8896         local cksum_param="osc.$FSNAME*.checksums"
8897         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8898         local checksum
8899         local i
8900
8901         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8902         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
8903         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
8904
8905         for i in 0 1; do
8906                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8907                         error "failed to set checksum=$i on MGS"
8908                 wait_update $HOSTNAME "$get_checksum" $i
8909                 #remount
8910                 echo "remount client, checksum should be $i"
8911                 remount_client $MOUNT || error "failed to remount client"
8912                 checksum=$(eval $get_checksum)
8913                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8914         done
8915         # remove persistent param to avoid races with checksum mountopt below
8916         do_facet mgs $LCTL set_param -P -d $cksum_param ||
8917                 error "failed to delete checksum on MGS"
8918
8919         for opt in "checksum" "nochecksum"; do
8920                 #remount with mount option
8921                 echo "remount client with option $opt, checksum should be $i"
8922                 umount_client $MOUNT || error "failed to umount client"
8923                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
8924                         error "failed to mount client with option '$opt'"
8925                 checksum=$(eval $get_checksum)
8926                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8927                 i=$((i - 1))
8928         done
8929
8930         remount_client $MOUNT || error "failed to remount client"
8931 }
8932 run_test 77k "enable/disable checksum correctly"
8933
8934 test_77l() {
8935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8936         $GSS && skip_env "could not run with gss"
8937
8938         set_checksums 1
8939         stack_trap "set_checksums $ORIG_CSUM" EXIT
8940         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
8941
8942         set_checksum_type invalid && error "unexpected success of invalid checksum type"
8943
8944         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8945         for algo in $CKSUM_TYPES; do
8946                 set_checksum_type $algo || error "fail to set checksum type $algo"
8947                 osc_algo=$(get_osc_checksum_type OST0000)
8948                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
8949
8950                 # no locks, no reqs to let the connection idle
8951                 cancel_lru_locks osc
8952                 lru_resize_disable osc
8953                 wait_osc_import_state client ost1 IDLE
8954
8955                 # ensure ost1 is connected
8956                 stat $DIR/$tfile >/dev/null || error "can't stat"
8957                 wait_osc_import_state client ost1 FULL
8958
8959                 osc_algo=$(get_osc_checksum_type OST0000)
8960                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
8961         done
8962         return 0
8963 }
8964 run_test 77l "preferred checksum type is remembered after reconnected"
8965
8966 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
8967 rm -f $F77_TMP
8968 unset F77_TMP
8969
8970 cleanup_test_78() {
8971         trap 0
8972         rm -f $DIR/$tfile
8973 }
8974
8975 test_78() { # bug 10901
8976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8977         remote_ost || skip_env "local OST"
8978
8979         NSEQ=5
8980         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
8981         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
8982         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
8983         echo "MemTotal: $MEMTOTAL"
8984
8985         # reserve 256MB of memory for the kernel and other running processes,
8986         # and then take 1/2 of the remaining memory for the read/write buffers.
8987         if [ $MEMTOTAL -gt 512 ] ;then
8988                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
8989         else
8990                 # for those poor memory-starved high-end clusters...
8991                 MEMTOTAL=$((MEMTOTAL / 2))
8992         fi
8993         echo "Mem to use for directio: $MEMTOTAL"
8994
8995         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
8996         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
8997         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
8998         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
8999                 head -n1)
9000         echo "Smallest OST: $SMALLESTOST"
9001         [[ $SMALLESTOST -lt 10240 ]] &&
9002                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9003
9004         trap cleanup_test_78 EXIT
9005
9006         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9007                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9008
9009         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9010         echo "File size: $F78SIZE"
9011         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9012         for i in $(seq 1 $NSEQ); do
9013                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9014                 echo directIO rdwr round $i of $NSEQ
9015                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9016         done
9017
9018         cleanup_test_78
9019 }
9020 run_test 78 "handle large O_DIRECT writes correctly ============"
9021
9022 test_79() { # bug 12743
9023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9024
9025         wait_delete_completed
9026
9027         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9028         BKFREE=$(calc_osc_kbytes kbytesfree)
9029         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9030
9031         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9032         DFTOTAL=`echo $STRING | cut -d, -f1`
9033         DFUSED=`echo $STRING  | cut -d, -f2`
9034         DFAVAIL=`echo $STRING | cut -d, -f3`
9035         DFFREE=$(($DFTOTAL - $DFUSED))
9036
9037         ALLOWANCE=$((64 * $OSTCOUNT))
9038
9039         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9040            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9041                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9042         fi
9043         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9044            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9045                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9046         fi
9047         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9048            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9049                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9050         fi
9051 }
9052 run_test 79 "df report consistency check ======================="
9053
9054 test_80() { # bug 10718
9055         remote_ost_nodsh && skip "remote OST with nodsh"
9056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9057
9058         # relax strong synchronous semantics for slow backends like ZFS
9059         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9060                 local soc="obdfilter.*.sync_lock_cancel"
9061                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9062
9063                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9064                 if [ -z "$save" ]; then
9065                         soc="obdfilter.*.sync_on_lock_cancel"
9066                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9067                 fi
9068
9069                 if [ "$save" != "never" ]; then
9070                         local hosts=$(comma_list $(osts_nodes))
9071
9072                         do_nodes $hosts $LCTL set_param $soc=never
9073                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9074                 fi
9075         fi
9076
9077         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9078         sync; sleep 1; sync
9079         local before=$(date +%s)
9080         cancel_lru_locks osc
9081         local after=$(date +%s)
9082         local diff=$((after - before))
9083         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9084
9085         rm -f $DIR/$tfile
9086 }
9087 run_test 80 "Page eviction is equally fast at high offsets too"
9088
9089 test_81a() { # LU-456
9090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9091         remote_ost_nodsh && skip "remote OST with nodsh"
9092
9093         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9094         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9095         do_facet ost1 lctl set_param fail_loc=0x80000228
9096
9097         # write should trigger a retry and success
9098         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9099         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9100         RC=$?
9101         if [ $RC -ne 0 ] ; then
9102                 error "write should success, but failed for $RC"
9103         fi
9104 }
9105 run_test 81a "OST should retry write when get -ENOSPC ==============="
9106
9107 test_81b() { # LU-456
9108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9109         remote_ost_nodsh && skip "remote OST with nodsh"
9110
9111         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9112         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9113         do_facet ost1 lctl set_param fail_loc=0x228
9114
9115         # write should retry several times and return -ENOSPC finally
9116         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9117         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9118         RC=$?
9119         ENOSPC=28
9120         if [ $RC -ne $ENOSPC ] ; then
9121                 error "dd should fail for -ENOSPC, but succeed."
9122         fi
9123 }
9124 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9125
9126 test_99() {
9127         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9128
9129         test_mkdir $DIR/$tdir.cvsroot
9130         chown $RUNAS_ID $DIR/$tdir.cvsroot
9131
9132         cd $TMP
9133         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9134
9135         cd /etc/init.d
9136         # some versions of cvs import exit(1) when asked to import links or
9137         # files they can't read.  ignore those files.
9138         local toignore=$(find . -type l -printf '-I %f\n' -o \
9139                          ! -perm /4 -printf '-I %f\n')
9140         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9141                 $tdir.reposname vtag rtag
9142
9143         cd $DIR
9144         test_mkdir $DIR/$tdir.reposname
9145         chown $RUNAS_ID $DIR/$tdir.reposname
9146         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9147
9148         cd $DIR/$tdir.reposname
9149         $RUNAS touch foo99
9150         $RUNAS cvs add -m 'addmsg' foo99
9151         $RUNAS cvs update
9152         $RUNAS cvs commit -m 'nomsg' foo99
9153         rm -fr $DIR/$tdir.cvsroot
9154 }
9155 run_test 99 "cvs strange file/directory operations"
9156
9157 test_100() {
9158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9159         [[ "$NETTYPE" =~ tcp ]] ||
9160                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9161         remote_ost_nodsh && skip "remote OST with nodsh"
9162         remote_mds_nodsh && skip "remote MDS with nodsh"
9163         remote_servers ||
9164                 skip "useless for local single node setup"
9165
9166         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9167                 [ "$PROT" != "tcp" ] && continue
9168                 RPORT=$(echo $REMOTE | cut -d: -f2)
9169                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9170
9171                 rc=0
9172                 LPORT=`echo $LOCAL | cut -d: -f2`
9173                 if [ $LPORT -ge 1024 ]; then
9174                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9175                         netstat -tna
9176                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9177                 fi
9178         done
9179         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9180 }
9181 run_test 100 "check local port using privileged port ==========="
9182
9183 function get_named_value()
9184 {
9185     local tag
9186
9187     tag=$1
9188     while read ;do
9189         line=$REPLY
9190         case $line in
9191         $tag*)
9192             echo $line | sed "s/^$tag[ ]*//"
9193             break
9194             ;;
9195         esac
9196     done
9197 }
9198
9199 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9200                    awk '/^max_cached_mb/ { print $2 }')
9201
9202 cleanup_101a() {
9203         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9204         trap 0
9205 }
9206
9207 test_101a() {
9208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9209
9210         local s
9211         local discard
9212         local nreads=10000
9213         local cache_limit=32
9214
9215         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9216         trap cleanup_101a EXIT
9217         $LCTL set_param -n llite.*.read_ahead_stats 0
9218         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9219
9220         #
9221         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9222         #
9223         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9224         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9225
9226         discard=0
9227         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9228                 get_named_value 'read but discarded' | cut -d" " -f1); do
9229                         discard=$(($discard + $s))
9230         done
9231         cleanup_101a
9232
9233         $LCTL get_param osc.*-osc*.rpc_stats
9234         $LCTL get_param llite.*.read_ahead_stats
9235
9236         # Discard is generally zero, but sometimes a few random reads line up
9237         # and trigger larger readahead, which is wasted & leads to discards.
9238         if [[ $(($discard)) -gt $nreads ]]; then
9239                 error "too many ($discard) discarded pages"
9240         fi
9241         rm -f $DIR/$tfile || true
9242 }
9243 run_test 101a "check read-ahead for random reads"
9244
9245 setup_test101bc() {
9246         test_mkdir $DIR/$tdir
9247         local ssize=$1
9248         local FILE_LENGTH=$2
9249         STRIPE_OFFSET=0
9250
9251         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9252
9253         local list=$(comma_list $(osts_nodes))
9254         set_osd_param $list '' read_cache_enable 0
9255         set_osd_param $list '' writethrough_cache_enable 0
9256
9257         trap cleanup_test101bc EXIT
9258         # prepare the read-ahead file
9259         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9260
9261         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9262                                 count=$FILE_SIZE_MB 2> /dev/null
9263
9264 }
9265
9266 cleanup_test101bc() {
9267         trap 0
9268         rm -rf $DIR/$tdir
9269         rm -f $DIR/$tfile
9270
9271         local list=$(comma_list $(osts_nodes))
9272         set_osd_param $list '' read_cache_enable 1
9273         set_osd_param $list '' writethrough_cache_enable 1
9274 }
9275
9276 calc_total() {
9277         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9278 }
9279
9280 ra_check_101() {
9281         local READ_SIZE=$1
9282         local STRIPE_SIZE=$2
9283         local FILE_LENGTH=$3
9284         local RA_INC=1048576
9285         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9286         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9287                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9288         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9289                         get_named_value 'read but discarded' |
9290                         cut -d" " -f1 | calc_total)
9291         if [[ $DISCARD -gt $discard_limit ]]; then
9292                 $LCTL get_param llite.*.read_ahead_stats
9293                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9294         else
9295                 echo "Read-ahead success for size ${READ_SIZE}"
9296         fi
9297 }
9298
9299 test_101b() {
9300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9301         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9302
9303         local STRIPE_SIZE=1048576
9304         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9305
9306         if [ $SLOW == "yes" ]; then
9307                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9308         else
9309                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9310         fi
9311
9312         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9313
9314         # prepare the read-ahead file
9315         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9316         cancel_lru_locks osc
9317         for BIDX in 2 4 8 16 32 64 128 256
9318         do
9319                 local BSIZE=$((BIDX*4096))
9320                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9321                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9322                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9323                 $LCTL set_param -n llite.*.read_ahead_stats 0
9324                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9325                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9326                 cancel_lru_locks osc
9327                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9328         done
9329         cleanup_test101bc
9330         true
9331 }
9332 run_test 101b "check stride-io mode read-ahead ================="
9333
9334 test_101c() {
9335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9336
9337         local STRIPE_SIZE=1048576
9338         local FILE_LENGTH=$((STRIPE_SIZE*100))
9339         local nreads=10000
9340         local rsize=65536
9341         local osc_rpc_stats
9342
9343         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9344
9345         cancel_lru_locks osc
9346         $LCTL set_param osc.*.rpc_stats 0
9347         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9348         $LCTL get_param osc.*.rpc_stats
9349         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9350                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9351                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9352                 local size
9353
9354                 if [ $lines -le 20 ]; then
9355                         echo "continue debug"
9356                         continue
9357                 fi
9358                 for size in 1 2 4 8; do
9359                         local rpc=$(echo "$stats" |
9360                                     awk '($1 == "'$size':") {print $2; exit; }')
9361                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9362                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9363                 done
9364                 echo "$osc_rpc_stats check passed!"
9365         done
9366         cleanup_test101bc
9367         true
9368 }
9369 run_test 101c "check stripe_size aligned read-ahead ================="
9370
9371 test_101d() {
9372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9373
9374         local file=$DIR/$tfile
9375         local sz_MB=${FILESIZE_101d:-80}
9376         local ra_MB=${READAHEAD_MB:-40}
9377
9378         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9379         [ $free_MB -lt $sz_MB ] &&
9380                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9381
9382         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9383         $LFS setstripe -c -1 $file || error "setstripe failed"
9384
9385         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9386         echo Cancel LRU locks on lustre client to flush the client cache
9387         cancel_lru_locks osc
9388
9389         echo Disable read-ahead
9390         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9391         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9392         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9393         $LCTL get_param -n llite.*.max_read_ahead_mb
9394
9395         echo "Reading the test file $file with read-ahead disabled"
9396         local sz_KB=$((sz_MB * 1024 / 4))
9397         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9398         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9399         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9400                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9401
9402         echo "Cancel LRU locks on lustre client to flush the client cache"
9403         cancel_lru_locks osc
9404         echo Enable read-ahead with ${ra_MB}MB
9405         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9406
9407         echo "Reading the test file $file with read-ahead enabled"
9408         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9409                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9410
9411         echo "read-ahead disabled time read $raOFF"
9412         echo "read-ahead enabled time read $raON"
9413
9414         rm -f $file
9415         wait_delete_completed
9416
9417         # use awk for this check instead of bash because it handles decimals
9418         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9419                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9420 }
9421 run_test 101d "file read with and without read-ahead enabled"
9422
9423 test_101e() {
9424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9425
9426         local file=$DIR/$tfile
9427         local size_KB=500  #KB
9428         local count=100
9429         local bsize=1024
9430
9431         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9432         local need_KB=$((count * size_KB))
9433         [[ $free_KB -le $need_KB ]] &&
9434                 skip_env "Need free space $need_KB, have $free_KB"
9435
9436         echo "Creating $count ${size_KB}K test files"
9437         for ((i = 0; i < $count; i++)); do
9438                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9439         done
9440
9441         echo "Cancel LRU locks on lustre client to flush the client cache"
9442         cancel_lru_locks $OSC
9443
9444         echo "Reset readahead stats"
9445         $LCTL set_param -n llite.*.read_ahead_stats 0
9446
9447         for ((i = 0; i < $count; i++)); do
9448                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9449         done
9450
9451         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9452                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9453
9454         for ((i = 0; i < $count; i++)); do
9455                 rm -rf $file.$i 2>/dev/null
9456         done
9457
9458         #10000 means 20% reads are missing in readahead
9459         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9460 }
9461 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9462
9463 test_101f() {
9464         which iozone || skip_env "no iozone installed"
9465
9466         local old_debug=$($LCTL get_param debug)
9467         old_debug=${old_debug#*=}
9468         $LCTL set_param debug="reada mmap"
9469
9470         # create a test file
9471         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9472
9473         echo Cancel LRU locks on lustre client to flush the client cache
9474         cancel_lru_locks osc
9475
9476         echo Reset readahead stats
9477         $LCTL set_param -n llite.*.read_ahead_stats 0
9478
9479         echo mmap read the file with small block size
9480         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9481                 > /dev/null 2>&1
9482
9483         echo checking missing pages
9484         $LCTL get_param llite.*.read_ahead_stats
9485         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9486                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9487
9488         $LCTL set_param debug="$old_debug"
9489         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9490         rm -f $DIR/$tfile
9491 }
9492 run_test 101f "check mmap read performance"
9493
9494 test_101g_brw_size_test() {
9495         local mb=$1
9496         local pages=$((mb * 1048576 / PAGE_SIZE))
9497         local file=$DIR/$tfile
9498
9499         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9500                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9501         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9502                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9503                         return 2
9504         done
9505
9506         stack_trap "rm -f $file" EXIT
9507         $LCTL set_param -n osc.*.rpc_stats=0
9508
9509         # 10 RPCs should be enough for the test
9510         local count=10
9511         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9512                 { error "dd write ${mb} MB blocks failed"; return 3; }
9513         cancel_lru_locks osc
9514         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9515                 { error "dd write ${mb} MB blocks failed"; return 4; }
9516
9517         # calculate number of full-sized read and write RPCs
9518         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9519                 sed -n '/pages per rpc/,/^$/p' |
9520                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9521                 END { print reads,writes }'))
9522         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
9523                 return 5
9524         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
9525                 return 6
9526
9527         return 0
9528 }
9529
9530 test_101g() {
9531         remote_ost_nodsh && skip "remote OST with nodsh"
9532
9533         local rpcs
9534         local osts=$(get_facets OST)
9535         local list=$(comma_list $(osts_nodes))
9536         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9537         local brw_size="obdfilter.*.brw_size"
9538
9539         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9540
9541         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9542
9543         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9544                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9545                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9546            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9547                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9548                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9549
9550                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9551                         suffix="M"
9552
9553                 if [[ $orig_mb -lt 16 ]]; then
9554                         save_lustre_params $osts "$brw_size" > $p
9555                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9556                                 error "set 16MB RPC size failed"
9557
9558                         echo "remount client to enable new RPC size"
9559                         remount_client $MOUNT || error "remount_client failed"
9560                 fi
9561
9562                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9563                 # should be able to set brw_size=12, but no rpc_stats for that
9564                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9565         fi
9566
9567         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9568
9569         if [[ $orig_mb -lt 16 ]]; then
9570                 restore_lustre_params < $p
9571                 remount_client $MOUNT || error "remount_client restore failed"
9572         fi
9573
9574         rm -f $p $DIR/$tfile
9575 }
9576 run_test 101g "Big bulk(4/16 MiB) readahead"
9577
9578 test_101h() {
9579         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9580
9581         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9582                 error "dd 70M file failed"
9583         echo Cancel LRU locks on lustre client to flush the client cache
9584         cancel_lru_locks osc
9585
9586         echo "Reset readahead stats"
9587         $LCTL set_param -n llite.*.read_ahead_stats 0
9588
9589         echo "Read 10M of data but cross 64M bundary"
9590         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9591         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9592                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9593         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9594         rm -f $p $DIR/$tfile
9595 }
9596 run_test 101h "Readahead should cover current read window"
9597
9598 test_101i() {
9599         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9600                 error "dd 10M file failed"
9601
9602         local max_per_file_mb=$($LCTL get_param -n \
9603                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9604         cancel_lru_locks osc
9605         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9606         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9607                 error "set max_read_ahead_per_file_mb to 1 failed"
9608
9609         echo "Reset readahead stats"
9610         $LCTL set_param llite.*.read_ahead_stats=0
9611
9612         dd if=$DIR/$tfile of=/dev/null bs=2M
9613
9614         $LCTL get_param llite.*.read_ahead_stats
9615         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9616                      awk '/misses/ { print $2 }')
9617         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9618         rm -f $DIR/$tfile
9619 }
9620 run_test 101i "allow current readahead to exceed reservation"
9621
9622 test_101j() {
9623         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9624                 error "setstripe $DIR/$tfile failed"
9625         local file_size=$((1048576 * 16))
9626         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9627         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9628
9629         echo Disable read-ahead
9630         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9631
9632         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9633         for blk in $PAGE_SIZE 1048576 $file_size; do
9634                 cancel_lru_locks osc
9635                 echo "Reset readahead stats"
9636                 $LCTL set_param -n llite.*.read_ahead_stats=0
9637                 local count=$(($file_size / $blk))
9638                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9639                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9640                              get_named_value 'failed to fast read' |
9641                              cut -d" " -f1 | calc_total)
9642                 $LCTL get_param -n llite.*.read_ahead_stats
9643                 [ $miss -eq $count ] || error "expected $count got $miss"
9644         done
9645
9646         rm -f $p $DIR/$tfile
9647 }
9648 run_test 101j "A complete read block should be submitted when no RA"
9649
9650 setup_test102() {
9651         test_mkdir $DIR/$tdir
9652         chown $RUNAS_ID $DIR/$tdir
9653         STRIPE_SIZE=65536
9654         STRIPE_OFFSET=1
9655         STRIPE_COUNT=$OSTCOUNT
9656         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9657
9658         trap cleanup_test102 EXIT
9659         cd $DIR
9660         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9661         cd $DIR/$tdir
9662         for num in 1 2 3 4; do
9663                 for count in $(seq 1 $STRIPE_COUNT); do
9664                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9665                                 local size=`expr $STRIPE_SIZE \* $num`
9666                                 local file=file"$num-$idx-$count"
9667                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9668                         done
9669                 done
9670         done
9671
9672         cd $DIR
9673         $1 tar cf $TMP/f102.tar $tdir --xattrs
9674 }
9675
9676 cleanup_test102() {
9677         trap 0
9678         rm -f $TMP/f102.tar
9679         rm -rf $DIR/d0.sanity/d102
9680 }
9681
9682 test_102a() {
9683         [ "$UID" != 0 ] && skip "must run as root"
9684         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9685                 skip_env "must have user_xattr"
9686
9687         [ -z "$(which setfattr 2>/dev/null)" ] &&
9688                 skip_env "could not find setfattr"
9689
9690         local testfile=$DIR/$tfile
9691
9692         touch $testfile
9693         echo "set/get xattr..."
9694         setfattr -n trusted.name1 -v value1 $testfile ||
9695                 error "setfattr -n trusted.name1=value1 $testfile failed"
9696         getfattr -n trusted.name1 $testfile 2> /dev/null |
9697           grep "trusted.name1=.value1" ||
9698                 error "$testfile missing trusted.name1=value1"
9699
9700         setfattr -n user.author1 -v author1 $testfile ||
9701                 error "setfattr -n user.author1=author1 $testfile failed"
9702         getfattr -n user.author1 $testfile 2> /dev/null |
9703           grep "user.author1=.author1" ||
9704                 error "$testfile missing trusted.author1=author1"
9705
9706         echo "listxattr..."
9707         setfattr -n trusted.name2 -v value2 $testfile ||
9708                 error "$testfile unable to set trusted.name2"
9709         setfattr -n trusted.name3 -v value3 $testfile ||
9710                 error "$testfile unable to set trusted.name3"
9711         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9712             grep "trusted.name" | wc -l) -eq 3 ] ||
9713                 error "$testfile missing 3 trusted.name xattrs"
9714
9715         setfattr -n user.author2 -v author2 $testfile ||
9716                 error "$testfile unable to set user.author2"
9717         setfattr -n user.author3 -v author3 $testfile ||
9718                 error "$testfile unable to set user.author3"
9719         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9720             grep "user.author" | wc -l) -eq 3 ] ||
9721                 error "$testfile missing 3 user.author xattrs"
9722
9723         echo "remove xattr..."
9724         setfattr -x trusted.name1 $testfile ||
9725                 error "$testfile error deleting trusted.name1"
9726         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9727                 error "$testfile did not delete trusted.name1 xattr"
9728
9729         setfattr -x user.author1 $testfile ||
9730                 error "$testfile error deleting user.author1"
9731         echo "set lustre special xattr ..."
9732         $LFS setstripe -c1 $testfile
9733         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9734                 awk -F "=" '/trusted.lov/ { print $2 }' )
9735         setfattr -n "trusted.lov" -v $lovea $testfile ||
9736                 error "$testfile doesn't ignore setting trusted.lov again"
9737         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9738                 error "$testfile allow setting invalid trusted.lov"
9739         rm -f $testfile
9740 }
9741 run_test 102a "user xattr test =================================="
9742
9743 check_102b_layout() {
9744         local layout="$*"
9745         local testfile=$DIR/$tfile
9746
9747         echo "test layout '$layout'"
9748         $LFS setstripe $layout $testfile || error "setstripe failed"
9749         $LFS getstripe -y $testfile
9750
9751         echo "get/set/list trusted.lov xattr ..." # b=10930
9752         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
9753         [[ "$value" =~ "trusted.lov" ]] ||
9754                 error "can't get trusted.lov from $testfile"
9755         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
9756                 error "getstripe failed"
9757
9758         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
9759
9760         value=$(cut -d= -f2 <<<$value)
9761         # LU-13168: truncated xattr should fail if short lov_user_md header
9762         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
9763                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
9764         for len in $lens; do
9765                 echo "setfattr $len $testfile.2"
9766                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
9767                         [ $len -lt 66 ] && error "short xattr len=$len worked"
9768         done
9769         local stripe_size=$($LFS getstripe -S $testfile.2)
9770         local stripe_count=$($LFS getstripe -c $testfile.2)
9771         [[ $stripe_size -eq 65536 ]] ||
9772                 error "stripe size $stripe_size != 65536"
9773         [[ $stripe_count -eq $stripe_count_orig ]] ||
9774                 error "stripe count $stripe_count != $stripe_count_orig"
9775         rm $testfile $testfile.2
9776 }
9777
9778 test_102b() {
9779         [ -z "$(which setfattr 2>/dev/null)" ] &&
9780                 skip_env "could not find setfattr"
9781         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9782
9783         # check plain layout
9784         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
9785
9786         # and also check composite layout
9787         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
9788
9789 }
9790 run_test 102b "getfattr/setfattr for trusted.lov EAs"
9791
9792 test_102c() {
9793         [ -z "$(which setfattr 2>/dev/null)" ] &&
9794                 skip_env "could not find setfattr"
9795         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9796
9797         # b10930: get/set/list lustre.lov xattr
9798         echo "get/set/list lustre.lov xattr ..."
9799         test_mkdir $DIR/$tdir
9800         chown $RUNAS_ID $DIR/$tdir
9801         local testfile=$DIR/$tdir/$tfile
9802         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9803                 error "setstripe failed"
9804         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9805                 error "getstripe failed"
9806         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9807         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9808
9809         local testfile2=${testfile}2
9810         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9811                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9812
9813         $RUNAS $MCREATE $testfile2
9814         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9815         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9816         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9817         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9818         [ $stripe_count -eq $STRIPECOUNT ] ||
9819                 error "stripe count $stripe_count != $STRIPECOUNT"
9820 }
9821 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9822
9823 compare_stripe_info1() {
9824         local stripe_index_all_zero=true
9825
9826         for num in 1 2 3 4; do
9827                 for count in $(seq 1 $STRIPE_COUNT); do
9828                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9829                                 local size=$((STRIPE_SIZE * num))
9830                                 local file=file"$num-$offset-$count"
9831                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9832                                 [[ $stripe_size -ne $size ]] &&
9833                                     error "$file: size $stripe_size != $size"
9834                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9835                                 # allow fewer stripes to be created, ORI-601
9836                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9837                                     error "$file: count $stripe_count != $count"
9838                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9839                                 [[ $stripe_index -ne 0 ]] &&
9840                                         stripe_index_all_zero=false
9841                         done
9842                 done
9843         done
9844         $stripe_index_all_zero &&
9845                 error "all files are being extracted starting from OST index 0"
9846         return 0
9847 }
9848
9849 have_xattrs_include() {
9850         tar --help | grep -q xattrs-include &&
9851                 echo --xattrs-include="lustre.*"
9852 }
9853
9854 test_102d() {
9855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9856         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9857
9858         XINC=$(have_xattrs_include)
9859         setup_test102
9860         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9861         cd $DIR/$tdir/$tdir
9862         compare_stripe_info1
9863 }
9864 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9865
9866 test_102f() {
9867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9868         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9869
9870         XINC=$(have_xattrs_include)
9871         setup_test102
9872         test_mkdir $DIR/$tdir.restore
9873         cd $DIR
9874         tar cf - --xattrs $tdir | tar xf - \
9875                 -C $DIR/$tdir.restore --xattrs $XINC
9876         cd $DIR/$tdir.restore/$tdir
9877         compare_stripe_info1
9878 }
9879 run_test 102f "tar copy files, not keep osts"
9880
9881 grow_xattr() {
9882         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9883                 skip "must have user_xattr"
9884         [ -z "$(which setfattr 2>/dev/null)" ] &&
9885                 skip_env "could not find setfattr"
9886         [ -z "$(which getfattr 2>/dev/null)" ] &&
9887                 skip_env "could not find getfattr"
9888
9889         local xsize=${1:-1024}  # in bytes
9890         local file=$DIR/$tfile
9891         local value="$(generate_string $xsize)"
9892         local xbig=trusted.big
9893         local toobig=$2
9894
9895         touch $file
9896         log "save $xbig on $file"
9897         if [ -z "$toobig" ]
9898         then
9899                 setfattr -n $xbig -v $value $file ||
9900                         error "saving $xbig on $file failed"
9901         else
9902                 setfattr -n $xbig -v $value $file &&
9903                         error "saving $xbig on $file succeeded"
9904                 return 0
9905         fi
9906
9907         local orig=$(get_xattr_value $xbig $file)
9908         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9909
9910         local xsml=trusted.sml
9911         log "save $xsml on $file"
9912         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
9913
9914         local new=$(get_xattr_value $xbig $file)
9915         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
9916
9917         log "grow $xsml on $file"
9918         setfattr -n $xsml -v "$value" $file ||
9919                 error "growing $xsml on $file failed"
9920
9921         new=$(get_xattr_value $xbig $file)
9922         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
9923         log "$xbig still valid after growing $xsml"
9924
9925         rm -f $file
9926 }
9927
9928 test_102h() { # bug 15777
9929         grow_xattr 1024
9930 }
9931 run_test 102h "grow xattr from inside inode to external block"
9932
9933 test_102ha() {
9934         large_xattr_enabled || skip_env "ea_inode feature disabled"
9935
9936         echo "setting xattr of max xattr size: $(max_xattr_size)"
9937         grow_xattr $(max_xattr_size)
9938
9939         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
9940         echo "This should fail:"
9941         grow_xattr $(($(max_xattr_size) + 10)) 1
9942 }
9943 run_test 102ha "grow xattr from inside inode to external inode"
9944
9945 test_102i() { # bug 17038
9946         [ -z "$(which getfattr 2>/dev/null)" ] &&
9947                 skip "could not find getfattr"
9948
9949         touch $DIR/$tfile
9950         ln -s $DIR/$tfile $DIR/${tfile}link
9951         getfattr -n trusted.lov $DIR/$tfile ||
9952                 error "lgetxattr on $DIR/$tfile failed"
9953         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
9954                 grep -i "no such attr" ||
9955                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
9956         rm -f $DIR/$tfile $DIR/${tfile}link
9957 }
9958 run_test 102i "lgetxattr test on symbolic link ============"
9959
9960 test_102j() {
9961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9962         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9963
9964         XINC=$(have_xattrs_include)
9965         setup_test102 "$RUNAS"
9966         chown $RUNAS_ID $DIR/$tdir
9967         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9968         cd $DIR/$tdir/$tdir
9969         compare_stripe_info1 "$RUNAS"
9970 }
9971 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
9972
9973 test_102k() {
9974         [ -z "$(which setfattr 2>/dev/null)" ] &&
9975                 skip "could not find setfattr"
9976
9977         touch $DIR/$tfile
9978         # b22187 just check that does not crash for regular file.
9979         setfattr -n trusted.lov $DIR/$tfile
9980         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
9981         local test_kdir=$DIR/$tdir
9982         test_mkdir $test_kdir
9983         local default_size=$($LFS getstripe -S $test_kdir)
9984         local default_count=$($LFS getstripe -c $test_kdir)
9985         local default_offset=$($LFS getstripe -i $test_kdir)
9986         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
9987                 error 'dir setstripe failed'
9988         setfattr -n trusted.lov $test_kdir
9989         local stripe_size=$($LFS getstripe -S $test_kdir)
9990         local stripe_count=$($LFS getstripe -c $test_kdir)
9991         local stripe_offset=$($LFS getstripe -i $test_kdir)
9992         [ $stripe_size -eq $default_size ] ||
9993                 error "stripe size $stripe_size != $default_size"
9994         [ $stripe_count -eq $default_count ] ||
9995                 error "stripe count $stripe_count != $default_count"
9996         [ $stripe_offset -eq $default_offset ] ||
9997                 error "stripe offset $stripe_offset != $default_offset"
9998         rm -rf $DIR/$tfile $test_kdir
9999 }
10000 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10001
10002 test_102l() {
10003         [ -z "$(which getfattr 2>/dev/null)" ] &&
10004                 skip "could not find getfattr"
10005
10006         # LU-532 trusted. xattr is invisible to non-root
10007         local testfile=$DIR/$tfile
10008
10009         touch $testfile
10010
10011         echo "listxattr as user..."
10012         chown $RUNAS_ID $testfile
10013         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10014             grep -q "trusted" &&
10015                 error "$testfile trusted xattrs are user visible"
10016
10017         return 0;
10018 }
10019 run_test 102l "listxattr size test =================================="
10020
10021 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10022         local path=$DIR/$tfile
10023         touch $path
10024
10025         listxattr_size_check $path || error "listattr_size_check $path failed"
10026 }
10027 run_test 102m "Ensure listxattr fails on small bufffer ========"
10028
10029 cleanup_test102
10030
10031 getxattr() { # getxattr path name
10032         # Return the base64 encoding of the value of xattr name on path.
10033         local path=$1
10034         local name=$2
10035
10036         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10037         # file: $path
10038         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10039         #
10040         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10041
10042         getfattr --absolute-names --encoding=base64 --name=$name $path |
10043                 awk -F= -v name=$name '$1 == name {
10044                         print substr($0, index($0, "=") + 1);
10045         }'
10046 }
10047
10048 test_102n() { # LU-4101 mdt: protect internal xattrs
10049         [ -z "$(which setfattr 2>/dev/null)" ] &&
10050                 skip "could not find setfattr"
10051         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10052         then
10053                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10054         fi
10055
10056         local file0=$DIR/$tfile.0
10057         local file1=$DIR/$tfile.1
10058         local xattr0=$TMP/$tfile.0
10059         local xattr1=$TMP/$tfile.1
10060         local namelist="lov lma lmv link fid version som hsm"
10061         local name
10062         local value
10063
10064         rm -rf $file0 $file1 $xattr0 $xattr1
10065         touch $file0 $file1
10066
10067         # Get 'before' xattrs of $file1.
10068         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10069
10070         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10071                 namelist+=" lfsck_namespace"
10072         for name in $namelist; do
10073                 # Try to copy xattr from $file0 to $file1.
10074                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10075
10076                 setfattr --name=trusted.$name --value="$value" $file1 ||
10077                         error "setxattr 'trusted.$name' failed"
10078
10079                 # Try to set a garbage xattr.
10080                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10081
10082                 if [[ x$name == "xlov" ]]; then
10083                         setfattr --name=trusted.lov --value="$value" $file1 &&
10084                         error "setxattr invalid 'trusted.lov' success"
10085                 else
10086                         setfattr --name=trusted.$name --value="$value" $file1 ||
10087                                 error "setxattr invalid 'trusted.$name' failed"
10088                 fi
10089
10090                 # Try to remove the xattr from $file1. We don't care if this
10091                 # appears to succeed or fail, we just don't want there to be
10092                 # any changes or crashes.
10093                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10094         done
10095
10096         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10097         then
10098                 name="lfsck_ns"
10099                 # Try to copy xattr from $file0 to $file1.
10100                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10101
10102                 setfattr --name=trusted.$name --value="$value" $file1 ||
10103                         error "setxattr 'trusted.$name' failed"
10104
10105                 # Try to set a garbage xattr.
10106                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10107
10108                 setfattr --name=trusted.$name --value="$value" $file1 ||
10109                         error "setxattr 'trusted.$name' failed"
10110
10111                 # Try to remove the xattr from $file1. We don't care if this
10112                 # appears to succeed or fail, we just don't want there to be
10113                 # any changes or crashes.
10114                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10115         fi
10116
10117         # Get 'after' xattrs of file1.
10118         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10119
10120         if ! diff $xattr0 $xattr1; then
10121                 error "before and after xattrs of '$file1' differ"
10122         fi
10123
10124         rm -rf $file0 $file1 $xattr0 $xattr1
10125
10126         return 0
10127 }
10128 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10129
10130 test_102p() { # LU-4703 setxattr did not check ownership
10131         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10132                 skip "MDS needs to be at least 2.5.56"
10133
10134         local testfile=$DIR/$tfile
10135
10136         touch $testfile
10137
10138         echo "setfacl as user..."
10139         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10140         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10141
10142         echo "setfattr as user..."
10143         setfacl -m "u:$RUNAS_ID:---" $testfile
10144         $RUNAS setfattr -x system.posix_acl_access $testfile
10145         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10146 }
10147 run_test 102p "check setxattr(2) correctly fails without permission"
10148
10149 test_102q() {
10150         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10151                 skip "MDS needs to be at least 2.6.92"
10152
10153         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10154 }
10155 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10156
10157 test_102r() {
10158         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10159                 skip "MDS needs to be at least 2.6.93"
10160
10161         touch $DIR/$tfile || error "touch"
10162         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10163         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10164         rm $DIR/$tfile || error "rm"
10165
10166         #normal directory
10167         mkdir -p $DIR/$tdir || error "mkdir"
10168         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10169         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10170         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10171                 error "$testfile error deleting user.author1"
10172         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10173                 grep "user.$(basename $tdir)" &&
10174                 error "$tdir did not delete user.$(basename $tdir)"
10175         rmdir $DIR/$tdir || error "rmdir"
10176
10177         #striped directory
10178         test_mkdir $DIR/$tdir
10179         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10180         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10181         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10182                 error "$testfile error deleting user.author1"
10183         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10184                 grep "user.$(basename $tdir)" &&
10185                 error "$tdir did not delete user.$(basename $tdir)"
10186         rmdir $DIR/$tdir || error "rm striped dir"
10187 }
10188 run_test 102r "set EAs with empty values"
10189
10190 test_102s() {
10191         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10192                 skip "MDS needs to be at least 2.11.52"
10193
10194         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10195
10196         save_lustre_params client "llite.*.xattr_cache" > $save
10197
10198         for cache in 0 1; do
10199                 lctl set_param llite.*.xattr_cache=$cache
10200
10201                 rm -f $DIR/$tfile
10202                 touch $DIR/$tfile || error "touch"
10203                 for prefix in lustre security system trusted user; do
10204                         # Note getxattr() may fail with 'Operation not
10205                         # supported' or 'No such attribute' depending
10206                         # on prefix and cache.
10207                         getfattr -n $prefix.n102s $DIR/$tfile &&
10208                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10209                 done
10210         done
10211
10212         restore_lustre_params < $save
10213 }
10214 run_test 102s "getting nonexistent xattrs should fail"
10215
10216 test_102t() {
10217         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10218                 skip "MDS needs to be at least 2.11.52"
10219
10220         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10221
10222         save_lustre_params client "llite.*.xattr_cache" > $save
10223
10224         for cache in 0 1; do
10225                 lctl set_param llite.*.xattr_cache=$cache
10226
10227                 for buf_size in 0 256; do
10228                         rm -f $DIR/$tfile
10229                         touch $DIR/$tfile || error "touch"
10230                         setfattr -n user.multiop $DIR/$tfile
10231                         $MULTIOP $DIR/$tfile oa$buf_size ||
10232                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10233                 done
10234         done
10235
10236         restore_lustre_params < $save
10237 }
10238 run_test 102t "zero length xattr values handled correctly"
10239
10240 run_acl_subtest()
10241 {
10242     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10243     return $?
10244 }
10245
10246 test_103a() {
10247         [ "$UID" != 0 ] && skip "must run as root"
10248         $GSS && skip_env "could not run under gss"
10249         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10250                 skip_env "must have acl enabled"
10251         [ -z "$(which setfacl 2>/dev/null)" ] &&
10252                 skip_env "could not find setfacl"
10253         remote_mds_nodsh && skip "remote MDS with nodsh"
10254
10255         gpasswd -a daemon bin                           # LU-5641
10256         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10257
10258         declare -a identity_old
10259
10260         for num in $(seq $MDSCOUNT); do
10261                 switch_identity $num true || identity_old[$num]=$?
10262         done
10263
10264         SAVE_UMASK=$(umask)
10265         umask 0022
10266         mkdir -p $DIR/$tdir
10267         cd $DIR/$tdir
10268
10269         echo "performing cp ..."
10270         run_acl_subtest cp || error "run_acl_subtest cp failed"
10271         echo "performing getfacl-noacl..."
10272         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10273         echo "performing misc..."
10274         run_acl_subtest misc || error  "misc test failed"
10275         echo "performing permissions..."
10276         run_acl_subtest permissions || error "permissions failed"
10277         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10278         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10279                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10280                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10281         then
10282                 echo "performing permissions xattr..."
10283                 run_acl_subtest permissions_xattr ||
10284                         error "permissions_xattr failed"
10285         fi
10286         echo "performing setfacl..."
10287         run_acl_subtest setfacl || error  "setfacl test failed"
10288
10289         # inheritance test got from HP
10290         echo "performing inheritance..."
10291         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10292         chmod +x make-tree || error "chmod +x failed"
10293         run_acl_subtest inheritance || error "inheritance test failed"
10294         rm -f make-tree
10295
10296         echo "LU-974 ignore umask when acl is enabled..."
10297         run_acl_subtest 974 || error "LU-974 umask test failed"
10298         if [ $MDSCOUNT -ge 2 ]; then
10299                 run_acl_subtest 974_remote ||
10300                         error "LU-974 umask test failed under remote dir"
10301         fi
10302
10303         echo "LU-2561 newly created file is same size as directory..."
10304         if [ "$mds1_FSTYPE" != "zfs" ]; then
10305                 run_acl_subtest 2561 || error "LU-2561 test failed"
10306         else
10307                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10308         fi
10309
10310         run_acl_subtest 4924 || error "LU-4924 test failed"
10311
10312         cd $SAVE_PWD
10313         umask $SAVE_UMASK
10314
10315         for num in $(seq $MDSCOUNT); do
10316                 if [ "${identity_old[$num]}" = 1 ]; then
10317                         switch_identity $num false || identity_old[$num]=$?
10318                 fi
10319         done
10320 }
10321 run_test 103a "acl test"
10322
10323 test_103b() {
10324         declare -a pids
10325         local U
10326
10327         for U in {0..511}; do
10328                 {
10329                 local O=$(printf "%04o" $U)
10330
10331                 umask $(printf "%04o" $((511 ^ $O)))
10332                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10333                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10334
10335                 (( $S == ($O & 0666) )) ||
10336                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10337
10338                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10339                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10340                 (( $S == ($O & 0666) )) ||
10341                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10342
10343                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10344                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10345                 (( $S == ($O & 0666) )) ||
10346                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10347                 rm -f $DIR/$tfile.[smp]$0
10348                 } &
10349                 local pid=$!
10350
10351                 # limit the concurrently running threads to 64. LU-11878
10352                 local idx=$((U % 64))
10353                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10354                 pids[idx]=$pid
10355         done
10356         wait
10357 }
10358 run_test 103b "umask lfs setstripe"
10359
10360 test_103c() {
10361         mkdir -p $DIR/$tdir
10362         cp -rp $DIR/$tdir $DIR/$tdir.bak
10363
10364         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10365                 error "$DIR/$tdir shouldn't contain default ACL"
10366         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10367                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10368         true
10369 }
10370 run_test 103c "'cp -rp' won't set empty acl"
10371
10372 test_104a() {
10373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10374
10375         touch $DIR/$tfile
10376         lfs df || error "lfs df failed"
10377         lfs df -ih || error "lfs df -ih failed"
10378         lfs df -h $DIR || error "lfs df -h $DIR failed"
10379         lfs df -i $DIR || error "lfs df -i $DIR failed"
10380         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10381         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10382
10383         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10384         lctl --device %$OSC deactivate
10385         lfs df || error "lfs df with deactivated OSC failed"
10386         lctl --device %$OSC activate
10387         # wait the osc back to normal
10388         wait_osc_import_ready client ost
10389
10390         lfs df || error "lfs df with reactivated OSC failed"
10391         rm -f $DIR/$tfile
10392 }
10393 run_test 104a "lfs df [-ih] [path] test ========================="
10394
10395 test_104b() {
10396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10397         [ $RUNAS_ID -eq $UID ] &&
10398                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10399
10400         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10401                         grep "Permission denied" | wc -l)))
10402         if [ $denied_cnt -ne 0 ]; then
10403                 error "lfs check servers test failed"
10404         fi
10405 }
10406 run_test 104b "$RUNAS lfs check servers test ===================="
10407
10408 test_105a() {
10409         # doesn't work on 2.4 kernels
10410         touch $DIR/$tfile
10411         if $(flock_is_enabled); then
10412                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10413         else
10414                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10415         fi
10416         rm -f $DIR/$tfile
10417 }
10418 run_test 105a "flock when mounted without -o flock test ========"
10419
10420 test_105b() {
10421         touch $DIR/$tfile
10422         if $(flock_is_enabled); then
10423                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10424         else
10425                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10426         fi
10427         rm -f $DIR/$tfile
10428 }
10429 run_test 105b "fcntl when mounted without -o flock test ========"
10430
10431 test_105c() {
10432         touch $DIR/$tfile
10433         if $(flock_is_enabled); then
10434                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10435         else
10436                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10437         fi
10438         rm -f $DIR/$tfile
10439 }
10440 run_test 105c "lockf when mounted without -o flock test"
10441
10442 test_105d() { # bug 15924
10443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10444
10445         test_mkdir $DIR/$tdir
10446         flock_is_enabled || skip_env "mount w/o flock enabled"
10447         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10448         $LCTL set_param fail_loc=0x80000315
10449         flocks_test 2 $DIR/$tdir
10450 }
10451 run_test 105d "flock race (should not freeze) ========"
10452
10453 test_105e() { # bug 22660 && 22040
10454         flock_is_enabled || skip_env "mount w/o flock enabled"
10455
10456         touch $DIR/$tfile
10457         flocks_test 3 $DIR/$tfile
10458 }
10459 run_test 105e "Two conflicting flocks from same process"
10460
10461 test_106() { #bug 10921
10462         test_mkdir $DIR/$tdir
10463         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10464         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10465 }
10466 run_test 106 "attempt exec of dir followed by chown of that dir"
10467
10468 test_107() {
10469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10470
10471         CDIR=`pwd`
10472         local file=core
10473
10474         cd $DIR
10475         rm -f $file
10476
10477         local save_pattern=$(sysctl -n kernel.core_pattern)
10478         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10479         sysctl -w kernel.core_pattern=$file
10480         sysctl -w kernel.core_uses_pid=0
10481
10482         ulimit -c unlimited
10483         sleep 60 &
10484         SLEEPPID=$!
10485
10486         sleep 1
10487
10488         kill -s 11 $SLEEPPID
10489         wait $SLEEPPID
10490         if [ -e $file ]; then
10491                 size=`stat -c%s $file`
10492                 [ $size -eq 0 ] && error "Fail to create core file $file"
10493         else
10494                 error "Fail to create core file $file"
10495         fi
10496         rm -f $file
10497         sysctl -w kernel.core_pattern=$save_pattern
10498         sysctl -w kernel.core_uses_pid=$save_uses_pid
10499         cd $CDIR
10500 }
10501 run_test 107 "Coredump on SIG"
10502
10503 test_110() {
10504         test_mkdir $DIR/$tdir
10505         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10506         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10507                 error "mkdir with 256 char should fail, but did not"
10508         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10509                 error "create with 255 char failed"
10510         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10511                 error "create with 256 char should fail, but did not"
10512
10513         ls -l $DIR/$tdir
10514         rm -rf $DIR/$tdir
10515 }
10516 run_test 110 "filename length checking"
10517
10518 #
10519 # Purpose: To verify dynamic thread (OSS) creation.
10520 #
10521 test_115() {
10522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10523         remote_ost_nodsh && skip "remote OST with nodsh"
10524
10525         # Lustre does not stop service threads once they are started.
10526         # Reset number of running threads to default.
10527         stopall
10528         setupall
10529
10530         local OSTIO_pre
10531         local save_params="$TMP/sanity-$TESTNAME.parameters"
10532
10533         # Get ll_ost_io count before I/O
10534         OSTIO_pre=$(do_facet ost1 \
10535                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10536         # Exit if lustre is not running (ll_ost_io not running).
10537         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10538
10539         echo "Starting with $OSTIO_pre threads"
10540         local thread_max=$((OSTIO_pre * 2))
10541         local rpc_in_flight=$((thread_max * 2))
10542         # Number of I/O Process proposed to be started.
10543         local nfiles
10544         local facets=$(get_facets OST)
10545
10546         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10547         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10548
10549         # Set in_flight to $rpc_in_flight
10550         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10551                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10552         nfiles=${rpc_in_flight}
10553         # Set ost thread_max to $thread_max
10554         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10555
10556         # 5 Minutes should be sufficient for max number of OSS
10557         # threads(thread_max) to be created.
10558         local timeout=300
10559
10560         # Start I/O.
10561         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10562         test_mkdir $DIR/$tdir
10563         for i in $(seq $nfiles); do
10564                 local file=$DIR/$tdir/${tfile}-$i
10565                 $LFS setstripe -c -1 -i 0 $file
10566                 ($WTL $file $timeout)&
10567         done
10568
10569         # I/O Started - Wait for thread_started to reach thread_max or report
10570         # error if thread_started is more than thread_max.
10571         echo "Waiting for thread_started to reach thread_max"
10572         local thread_started=0
10573         local end_time=$((SECONDS + timeout))
10574
10575         while [ $SECONDS -le $end_time ] ; do
10576                 echo -n "."
10577                 # Get ost i/o thread_started count.
10578                 thread_started=$(do_facet ost1 \
10579                         "$LCTL get_param \
10580                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10581                 # Break out if thread_started is equal/greater than thread_max
10582                 if [[ $thread_started -ge $thread_max ]]; then
10583                         echo ll_ost_io thread_started $thread_started, \
10584                                 equal/greater than thread_max $thread_max
10585                         break
10586                 fi
10587                 sleep 1
10588         done
10589
10590         # Cleanup - We have the numbers, Kill i/o jobs if running.
10591         jobcount=($(jobs -p))
10592         for i in $(seq 0 $((${#jobcount[@]}-1)))
10593         do
10594                 kill -9 ${jobcount[$i]}
10595                 if [ $? -ne 0 ] ; then
10596                         echo Warning: \
10597                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10598                 fi
10599         done
10600
10601         # Cleanup files left by WTL binary.
10602         for i in $(seq $nfiles); do
10603                 local file=$DIR/$tdir/${tfile}-$i
10604                 rm -rf $file
10605                 if [ $? -ne 0 ] ; then
10606                         echo "Warning: Failed to delete file $file"
10607                 fi
10608         done
10609
10610         restore_lustre_params <$save_params
10611         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10612
10613         # Error out if no new thread has started or Thread started is greater
10614         # than thread max.
10615         if [[ $thread_started -le $OSTIO_pre ||
10616                         $thread_started -gt $thread_max ]]; then
10617                 error "ll_ost_io: thread_started $thread_started" \
10618                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10619                       "No new thread started or thread started greater " \
10620                       "than thread_max."
10621         fi
10622 }
10623 run_test 115 "verify dynamic thread creation===================="
10624
10625 free_min_max () {
10626         wait_delete_completed
10627         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10628         echo "OST kbytes available: ${AVAIL[@]}"
10629         MAXV=${AVAIL[0]}
10630         MAXI=0
10631         MINV=${AVAIL[0]}
10632         MINI=0
10633         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10634                 #echo OST $i: ${AVAIL[i]}kb
10635                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10636                         MAXV=${AVAIL[i]}
10637                         MAXI=$i
10638                 fi
10639                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10640                         MINV=${AVAIL[i]}
10641                         MINI=$i
10642                 fi
10643         done
10644         echo "Min free space: OST $MINI: $MINV"
10645         echo "Max free space: OST $MAXI: $MAXV"
10646 }
10647
10648 test_116a() { # was previously test_116()
10649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10650         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10651         remote_mds_nodsh && skip "remote MDS with nodsh"
10652
10653         echo -n "Free space priority "
10654         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10655                 head -n1
10656         declare -a AVAIL
10657         free_min_max
10658
10659         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10660         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10661         trap simple_cleanup_common EXIT
10662
10663         # Check if we need to generate uneven OSTs
10664         test_mkdir -p $DIR/$tdir/OST${MINI}
10665         local FILL=$((MINV / 4))
10666         local DIFF=$((MAXV - MINV))
10667         local DIFF2=$((DIFF * 100 / MINV))
10668
10669         local threshold=$(do_facet $SINGLEMDS \
10670                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10671         threshold=${threshold%%%}
10672         echo -n "Check for uneven OSTs: "
10673         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10674
10675         if [[ $DIFF2 -gt $threshold ]]; then
10676                 echo "ok"
10677                 echo "Don't need to fill OST$MINI"
10678         else
10679                 # generate uneven OSTs. Write 2% over the QOS threshold value
10680                 echo "no"
10681                 DIFF=$((threshold - DIFF2 + 2))
10682                 DIFF2=$((MINV * DIFF / 100))
10683                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10684                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10685                         error "setstripe failed"
10686                 DIFF=$((DIFF2 / 2048))
10687                 i=0
10688                 while [ $i -lt $DIFF ]; do
10689                         i=$((i + 1))
10690                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10691                                 bs=2M count=1 2>/dev/null
10692                         echo -n .
10693                 done
10694                 echo .
10695                 sync
10696                 sleep_maxage
10697                 free_min_max
10698         fi
10699
10700         DIFF=$((MAXV - MINV))
10701         DIFF2=$((DIFF * 100 / MINV))
10702         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10703         if [ $DIFF2 -gt $threshold ]; then
10704                 echo "ok"
10705         else
10706                 echo "failed - QOS mode won't be used"
10707                 simple_cleanup_common
10708                 skip "QOS imbalance criteria not met"
10709         fi
10710
10711         MINI1=$MINI
10712         MINV1=$MINV
10713         MAXI1=$MAXI
10714         MAXV1=$MAXV
10715
10716         # now fill using QOS
10717         $LFS setstripe -c 1 $DIR/$tdir
10718         FILL=$((FILL / 200))
10719         if [ $FILL -gt 600 ]; then
10720                 FILL=600
10721         fi
10722         echo "writing $FILL files to QOS-assigned OSTs"
10723         i=0
10724         while [ $i -lt $FILL ]; do
10725                 i=$((i + 1))
10726                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10727                         count=1 2>/dev/null
10728                 echo -n .
10729         done
10730         echo "wrote $i 200k files"
10731         sync
10732         sleep_maxage
10733
10734         echo "Note: free space may not be updated, so measurements might be off"
10735         free_min_max
10736         DIFF2=$((MAXV - MINV))
10737         echo "free space delta: orig $DIFF final $DIFF2"
10738         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10739         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10740         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10741         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10742         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10743         if [[ $DIFF -gt 0 ]]; then
10744                 FILL=$((DIFF2 * 100 / DIFF - 100))
10745                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10746         fi
10747
10748         # Figure out which files were written where
10749         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10750                awk '/'$MINI1': / {print $2; exit}')
10751         echo $UUID
10752         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10753         echo "$MINC files created on smaller OST $MINI1"
10754         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10755                awk '/'$MAXI1': / {print $2; exit}')
10756         echo $UUID
10757         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10758         echo "$MAXC files created on larger OST $MAXI1"
10759         if [[ $MINC -gt 0 ]]; then
10760                 FILL=$((MAXC * 100 / MINC - 100))
10761                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10762         fi
10763         [[ $MAXC -gt $MINC ]] ||
10764                 error_ignore LU-9 "stripe QOS didn't balance free space"
10765         simple_cleanup_common
10766 }
10767 run_test 116a "stripe QOS: free space balance ==================="
10768
10769 test_116b() { # LU-2093
10770         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10771         remote_mds_nodsh && skip "remote MDS with nodsh"
10772
10773 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10774         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10775                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10776         [ -z "$old_rr" ] && skip "no QOS"
10777         do_facet $SINGLEMDS lctl set_param \
10778                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10779         mkdir -p $DIR/$tdir
10780         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10781         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10782         do_facet $SINGLEMDS lctl set_param fail_loc=0
10783         rm -rf $DIR/$tdir
10784         do_facet $SINGLEMDS lctl set_param \
10785                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10786 }
10787 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10788
10789 test_117() # bug 10891
10790 {
10791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10792
10793         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10794         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10795         lctl set_param fail_loc=0x21e
10796         > $DIR/$tfile || error "truncate failed"
10797         lctl set_param fail_loc=0
10798         echo "Truncate succeeded."
10799         rm -f $DIR/$tfile
10800 }
10801 run_test 117 "verify osd extend =========="
10802
10803 NO_SLOW_RESENDCOUNT=4
10804 export OLD_RESENDCOUNT=""
10805 set_resend_count () {
10806         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10807         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10808         lctl set_param -n $PROC_RESENDCOUNT $1
10809         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10810 }
10811
10812 # for reduce test_118* time (b=14842)
10813 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10814
10815 # Reset async IO behavior after error case
10816 reset_async() {
10817         FILE=$DIR/reset_async
10818
10819         # Ensure all OSCs are cleared
10820         $LFS setstripe -c -1 $FILE
10821         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10822         sync
10823         rm $FILE
10824 }
10825
10826 test_118a() #bug 11710
10827 {
10828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10829
10830         reset_async
10831
10832         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10833         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10834         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10835
10836         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10837                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10838                 return 1;
10839         fi
10840         rm -f $DIR/$tfile
10841 }
10842 run_test 118a "verify O_SYNC works =========="
10843
10844 test_118b()
10845 {
10846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10847         remote_ost_nodsh && skip "remote OST with nodsh"
10848
10849         reset_async
10850
10851         #define OBD_FAIL_SRV_ENOENT 0x217
10852         set_nodes_failloc "$(osts_nodes)" 0x217
10853         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10854         RC=$?
10855         set_nodes_failloc "$(osts_nodes)" 0
10856         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10857         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10858                     grep -c writeback)
10859
10860         if [[ $RC -eq 0 ]]; then
10861                 error "Must return error due to dropped pages, rc=$RC"
10862                 return 1;
10863         fi
10864
10865         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10866                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10867                 return 1;
10868         fi
10869
10870         echo "Dirty pages not leaked on ENOENT"
10871
10872         # Due to the above error the OSC will issue all RPCs syncronously
10873         # until a subsequent RPC completes successfully without error.
10874         $MULTIOP $DIR/$tfile Ow4096yc
10875         rm -f $DIR/$tfile
10876
10877         return 0
10878 }
10879 run_test 118b "Reclaim dirty pages on fatal error =========="
10880
10881 test_118c()
10882 {
10883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10884
10885         # for 118c, restore the original resend count, LU-1940
10886         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10887                                 set_resend_count $OLD_RESENDCOUNT
10888         remote_ost_nodsh && skip "remote OST with nodsh"
10889
10890         reset_async
10891
10892         #define OBD_FAIL_OST_EROFS               0x216
10893         set_nodes_failloc "$(osts_nodes)" 0x216
10894
10895         # multiop should block due to fsync until pages are written
10896         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10897         MULTIPID=$!
10898         sleep 1
10899
10900         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10901                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10902         fi
10903
10904         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10905                     grep -c writeback)
10906         if [[ $WRITEBACK -eq 0 ]]; then
10907                 error "No page in writeback, writeback=$WRITEBACK"
10908         fi
10909
10910         set_nodes_failloc "$(osts_nodes)" 0
10911         wait $MULTIPID
10912         RC=$?
10913         if [[ $RC -ne 0 ]]; then
10914                 error "Multiop fsync failed, rc=$RC"
10915         fi
10916
10917         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10918         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10919                     grep -c writeback)
10920         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10921                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10922         fi
10923
10924         rm -f $DIR/$tfile
10925         echo "Dirty pages flushed via fsync on EROFS"
10926         return 0
10927 }
10928 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
10929
10930 # continue to use small resend count to reduce test_118* time (b=14842)
10931 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10932
10933 test_118d()
10934 {
10935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10936         remote_ost_nodsh && skip "remote OST with nodsh"
10937
10938         reset_async
10939
10940         #define OBD_FAIL_OST_BRW_PAUSE_BULK
10941         set_nodes_failloc "$(osts_nodes)" 0x214
10942         # multiop should block due to fsync until pages are written
10943         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10944         MULTIPID=$!
10945         sleep 1
10946
10947         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10948                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10949         fi
10950
10951         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10952                     grep -c writeback)
10953         if [[ $WRITEBACK -eq 0 ]]; then
10954                 error "No page in writeback, writeback=$WRITEBACK"
10955         fi
10956
10957         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
10958         set_nodes_failloc "$(osts_nodes)" 0
10959
10960         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10961         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10962                     grep -c writeback)
10963         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10964                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10965         fi
10966
10967         rm -f $DIR/$tfile
10968         echo "Dirty pages gaurenteed flushed via fsync"
10969         return 0
10970 }
10971 run_test 118d "Fsync validation inject a delay of the bulk =========="
10972
10973 test_118f() {
10974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10975
10976         reset_async
10977
10978         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
10979         lctl set_param fail_loc=0x8000040a
10980
10981         # Should simulate EINVAL error which is fatal
10982         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10983         RC=$?
10984         if [[ $RC -eq 0 ]]; then
10985                 error "Must return error due to dropped pages, rc=$RC"
10986         fi
10987
10988         lctl set_param fail_loc=0x0
10989
10990         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10991         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10992         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10993                     grep -c writeback)
10994         if [[ $LOCKED -ne 0 ]]; then
10995                 error "Locked pages remain in cache, locked=$LOCKED"
10996         fi
10997
10998         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10999                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11000         fi
11001
11002         rm -f $DIR/$tfile
11003         echo "No pages locked after fsync"
11004
11005         reset_async
11006         return 0
11007 }
11008 run_test 118f "Simulate unrecoverable OSC side error =========="
11009
11010 test_118g() {
11011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11012
11013         reset_async
11014
11015         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11016         lctl set_param fail_loc=0x406
11017
11018         # simulate local -ENOMEM
11019         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11020         RC=$?
11021
11022         lctl set_param fail_loc=0
11023         if [[ $RC -eq 0 ]]; then
11024                 error "Must return error due to dropped pages, rc=$RC"
11025         fi
11026
11027         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11028         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11029         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11030                         grep -c writeback)
11031         if [[ $LOCKED -ne 0 ]]; then
11032                 error "Locked pages remain in cache, locked=$LOCKED"
11033         fi
11034
11035         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11036                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11037         fi
11038
11039         rm -f $DIR/$tfile
11040         echo "No pages locked after fsync"
11041
11042         reset_async
11043         return 0
11044 }
11045 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11046
11047 test_118h() {
11048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11049         remote_ost_nodsh && skip "remote OST with nodsh"
11050
11051         reset_async
11052
11053         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11054         set_nodes_failloc "$(osts_nodes)" 0x20e
11055         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11056         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11057         RC=$?
11058
11059         set_nodes_failloc "$(osts_nodes)" 0
11060         if [[ $RC -eq 0 ]]; then
11061                 error "Must return error due to dropped pages, rc=$RC"
11062         fi
11063
11064         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11065         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11066         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11067                     grep -c writeback)
11068         if [[ $LOCKED -ne 0 ]]; then
11069                 error "Locked pages remain in cache, locked=$LOCKED"
11070         fi
11071
11072         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11073                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11074         fi
11075
11076         rm -f $DIR/$tfile
11077         echo "No pages locked after fsync"
11078
11079         return 0
11080 }
11081 run_test 118h "Verify timeout in handling recoverables errors  =========="
11082
11083 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11084
11085 test_118i() {
11086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11087         remote_ost_nodsh && skip "remote OST with nodsh"
11088
11089         reset_async
11090
11091         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11092         set_nodes_failloc "$(osts_nodes)" 0x20e
11093
11094         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11095         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11096         PID=$!
11097         sleep 5
11098         set_nodes_failloc "$(osts_nodes)" 0
11099
11100         wait $PID
11101         RC=$?
11102         if [[ $RC -ne 0 ]]; then
11103                 error "got error, but should be not, rc=$RC"
11104         fi
11105
11106         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11107         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11108         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11109         if [[ $LOCKED -ne 0 ]]; then
11110                 error "Locked pages remain in cache, locked=$LOCKED"
11111         fi
11112
11113         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11114                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11115         fi
11116
11117         rm -f $DIR/$tfile
11118         echo "No pages locked after fsync"
11119
11120         return 0
11121 }
11122 run_test 118i "Fix error before timeout in recoverable error  =========="
11123
11124 [ "$SLOW" = "no" ] && set_resend_count 4
11125
11126 test_118j() {
11127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11128         remote_ost_nodsh && skip "remote OST with nodsh"
11129
11130         reset_async
11131
11132         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11133         set_nodes_failloc "$(osts_nodes)" 0x220
11134
11135         # return -EIO from OST
11136         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11137         RC=$?
11138         set_nodes_failloc "$(osts_nodes)" 0x0
11139         if [[ $RC -eq 0 ]]; then
11140                 error "Must return error due to dropped pages, rc=$RC"
11141         fi
11142
11143         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11144         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11145         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11146         if [[ $LOCKED -ne 0 ]]; then
11147                 error "Locked pages remain in cache, locked=$LOCKED"
11148         fi
11149
11150         # in recoverable error on OST we want resend and stay until it finished
11151         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11152                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11153         fi
11154
11155         rm -f $DIR/$tfile
11156         echo "No pages locked after fsync"
11157
11158         return 0
11159 }
11160 run_test 118j "Simulate unrecoverable OST side error =========="
11161
11162 test_118k()
11163 {
11164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11165         remote_ost_nodsh && skip "remote OSTs with nodsh"
11166
11167         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11168         set_nodes_failloc "$(osts_nodes)" 0x20e
11169         test_mkdir $DIR/$tdir
11170
11171         for ((i=0;i<10;i++)); do
11172                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11173                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11174                 SLEEPPID=$!
11175                 sleep 0.500s
11176                 kill $SLEEPPID
11177                 wait $SLEEPPID
11178         done
11179
11180         set_nodes_failloc "$(osts_nodes)" 0
11181         rm -rf $DIR/$tdir
11182 }
11183 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11184
11185 test_118l() # LU-646
11186 {
11187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11188
11189         test_mkdir $DIR/$tdir
11190         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11191         rm -rf $DIR/$tdir
11192 }
11193 run_test 118l "fsync dir"
11194
11195 test_118m() # LU-3066
11196 {
11197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11198
11199         test_mkdir $DIR/$tdir
11200         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11201         rm -rf $DIR/$tdir
11202 }
11203 run_test 118m "fdatasync dir ========="
11204
11205 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11206
11207 test_118n()
11208 {
11209         local begin
11210         local end
11211
11212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11213         remote_ost_nodsh && skip "remote OSTs with nodsh"
11214
11215         # Sleep to avoid a cached response.
11216         #define OBD_STATFS_CACHE_SECONDS 1
11217         sleep 2
11218
11219         # Inject a 10 second delay in the OST_STATFS handler.
11220         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11221         set_nodes_failloc "$(osts_nodes)" 0x242
11222
11223         begin=$SECONDS
11224         stat --file-system $MOUNT > /dev/null
11225         end=$SECONDS
11226
11227         set_nodes_failloc "$(osts_nodes)" 0
11228
11229         if ((end - begin > 20)); then
11230             error "statfs took $((end - begin)) seconds, expected 10"
11231         fi
11232 }
11233 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11234
11235 test_119a() # bug 11737
11236 {
11237         BSIZE=$((512 * 1024))
11238         directio write $DIR/$tfile 0 1 $BSIZE
11239         # We ask to read two blocks, which is more than a file size.
11240         # directio will indicate an error when requested and actual
11241         # sizes aren't equeal (a normal situation in this case) and
11242         # print actual read amount.
11243         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11244         if [ "$NOB" != "$BSIZE" ]; then
11245                 error "read $NOB bytes instead of $BSIZE"
11246         fi
11247         rm -f $DIR/$tfile
11248 }
11249 run_test 119a "Short directIO read must return actual read amount"
11250
11251 test_119b() # bug 11737
11252 {
11253         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11254
11255         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11256         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11257         sync
11258         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11259                 error "direct read failed"
11260         rm -f $DIR/$tfile
11261 }
11262 run_test 119b "Sparse directIO read must return actual read amount"
11263
11264 test_119c() # bug 13099
11265 {
11266         BSIZE=1048576
11267         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11268         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11269         rm -f $DIR/$tfile
11270 }
11271 run_test 119c "Testing for direct read hitting hole"
11272
11273 test_119d() # bug 15950
11274 {
11275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11276
11277         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11278         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11279         BSIZE=1048576
11280         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11281         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11282         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11283         lctl set_param fail_loc=0x40d
11284         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11285         pid_dio=$!
11286         sleep 1
11287         cat $DIR/$tfile > /dev/null &
11288         lctl set_param fail_loc=0
11289         pid_reads=$!
11290         wait $pid_dio
11291         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11292         sleep 2
11293         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11294         error "the read rpcs have not completed in 2s"
11295         rm -f $DIR/$tfile
11296         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11297 }
11298 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11299
11300 test_120a() {
11301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11302         remote_mds_nodsh && skip "remote MDS with nodsh"
11303         test_mkdir -i0 -c1 $DIR/$tdir
11304         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11305                 skip_env "no early lock cancel on server"
11306
11307         lru_resize_disable mdc
11308         lru_resize_disable osc
11309         cancel_lru_locks mdc
11310         # asynchronous object destroy at MDT could cause bl ast to client
11311         cancel_lru_locks osc
11312
11313         stat $DIR/$tdir > /dev/null
11314         can1=$(do_facet mds1 \
11315                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11316                awk '/ldlm_cancel/ {print $2}')
11317         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11318                awk '/ldlm_bl_callback/ {print $2}')
11319         test_mkdir -i0 -c1 $DIR/$tdir/d1
11320         can2=$(do_facet mds1 \
11321                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11322                awk '/ldlm_cancel/ {print $2}')
11323         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11324                awk '/ldlm_bl_callback/ {print $2}')
11325         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11326         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11327         lru_resize_enable mdc
11328         lru_resize_enable osc
11329 }
11330 run_test 120a "Early Lock Cancel: mkdir test"
11331
11332 test_120b() {
11333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11334         remote_mds_nodsh && skip "remote MDS with nodsh"
11335         test_mkdir $DIR/$tdir
11336         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11337                 skip_env "no early lock cancel on server"
11338
11339         lru_resize_disable mdc
11340         lru_resize_disable osc
11341         cancel_lru_locks mdc
11342         stat $DIR/$tdir > /dev/null
11343         can1=$(do_facet $SINGLEMDS \
11344                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11345                awk '/ldlm_cancel/ {print $2}')
11346         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11347                awk '/ldlm_bl_callback/ {print $2}')
11348         touch $DIR/$tdir/f1
11349         can2=$(do_facet $SINGLEMDS \
11350                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11351                awk '/ldlm_cancel/ {print $2}')
11352         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11353                awk '/ldlm_bl_callback/ {print $2}')
11354         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11355         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11356         lru_resize_enable mdc
11357         lru_resize_enable osc
11358 }
11359 run_test 120b "Early Lock Cancel: create test"
11360
11361 test_120c() {
11362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11363         remote_mds_nodsh && skip "remote MDS with nodsh"
11364         test_mkdir -i0 -c1 $DIR/$tdir
11365         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11366                 skip "no early lock cancel on server"
11367
11368         lru_resize_disable mdc
11369         lru_resize_disable osc
11370         test_mkdir -i0 -c1 $DIR/$tdir/d1
11371         test_mkdir -i0 -c1 $DIR/$tdir/d2
11372         touch $DIR/$tdir/d1/f1
11373         cancel_lru_locks mdc
11374         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11375         can1=$(do_facet mds1 \
11376                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11377                awk '/ldlm_cancel/ {print $2}')
11378         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11379                awk '/ldlm_bl_callback/ {print $2}')
11380         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11381         can2=$(do_facet mds1 \
11382                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11383                awk '/ldlm_cancel/ {print $2}')
11384         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11385                awk '/ldlm_bl_callback/ {print $2}')
11386         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11387         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11388         lru_resize_enable mdc
11389         lru_resize_enable osc
11390 }
11391 run_test 120c "Early Lock Cancel: link test"
11392
11393 test_120d() {
11394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11395         remote_mds_nodsh && skip "remote MDS with nodsh"
11396         test_mkdir -i0 -c1 $DIR/$tdir
11397         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11398                 skip_env "no early lock cancel on server"
11399
11400         lru_resize_disable mdc
11401         lru_resize_disable osc
11402         touch $DIR/$tdir
11403         cancel_lru_locks mdc
11404         stat $DIR/$tdir > /dev/null
11405         can1=$(do_facet mds1 \
11406                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11407                awk '/ldlm_cancel/ {print $2}')
11408         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11409                awk '/ldlm_bl_callback/ {print $2}')
11410         chmod a+x $DIR/$tdir
11411         can2=$(do_facet mds1 \
11412                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11413                awk '/ldlm_cancel/ {print $2}')
11414         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11415                awk '/ldlm_bl_callback/ {print $2}')
11416         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11417         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11418         lru_resize_enable mdc
11419         lru_resize_enable osc
11420 }
11421 run_test 120d "Early Lock Cancel: setattr test"
11422
11423 test_120e() {
11424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11425         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11426                 skip_env "no early lock cancel on server"
11427         remote_mds_nodsh && skip "remote MDS with nodsh"
11428
11429         local dlmtrace_set=false
11430
11431         test_mkdir -i0 -c1 $DIR/$tdir
11432         lru_resize_disable mdc
11433         lru_resize_disable osc
11434         ! $LCTL get_param debug | grep -q dlmtrace &&
11435                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11436         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11437         cancel_lru_locks mdc
11438         cancel_lru_locks osc
11439         dd if=$DIR/$tdir/f1 of=/dev/null
11440         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11441         # XXX client can not do early lock cancel of OST lock
11442         # during unlink (LU-4206), so cancel osc lock now.
11443         sleep 2
11444         cancel_lru_locks osc
11445         can1=$(do_facet mds1 \
11446                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11447                awk '/ldlm_cancel/ {print $2}')
11448         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11449                awk '/ldlm_bl_callback/ {print $2}')
11450         unlink $DIR/$tdir/f1
11451         sleep 5
11452         can2=$(do_facet mds1 \
11453                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11454                awk '/ldlm_cancel/ {print $2}')
11455         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11456                awk '/ldlm_bl_callback/ {print $2}')
11457         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11458                 $LCTL dk $TMP/cancel.debug.txt
11459         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11460                 $LCTL dk $TMP/blocking.debug.txt
11461         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11462         lru_resize_enable mdc
11463         lru_resize_enable osc
11464 }
11465 run_test 120e "Early Lock Cancel: unlink test"
11466
11467 test_120f() {
11468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11469         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11470                 skip_env "no early lock cancel on server"
11471         remote_mds_nodsh && skip "remote MDS with nodsh"
11472
11473         test_mkdir -i0 -c1 $DIR/$tdir
11474         lru_resize_disable mdc
11475         lru_resize_disable osc
11476         test_mkdir -i0 -c1 $DIR/$tdir/d1
11477         test_mkdir -i0 -c1 $DIR/$tdir/d2
11478         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11479         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11480         cancel_lru_locks mdc
11481         cancel_lru_locks osc
11482         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11483         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11484         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11485         # XXX client can not do early lock cancel of OST lock
11486         # during rename (LU-4206), so cancel osc lock now.
11487         sleep 2
11488         cancel_lru_locks osc
11489         can1=$(do_facet mds1 \
11490                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11491                awk '/ldlm_cancel/ {print $2}')
11492         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11493                awk '/ldlm_bl_callback/ {print $2}')
11494         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11495         sleep 5
11496         can2=$(do_facet mds1 \
11497                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11498                awk '/ldlm_cancel/ {print $2}')
11499         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11500                awk '/ldlm_bl_callback/ {print $2}')
11501         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11502         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11503         lru_resize_enable mdc
11504         lru_resize_enable osc
11505 }
11506 run_test 120f "Early Lock Cancel: rename test"
11507
11508 test_120g() {
11509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11510         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11511                 skip_env "no early lock cancel on server"
11512         remote_mds_nodsh && skip "remote MDS with nodsh"
11513
11514         lru_resize_disable mdc
11515         lru_resize_disable osc
11516         count=10000
11517         echo create $count files
11518         test_mkdir $DIR/$tdir
11519         cancel_lru_locks mdc
11520         cancel_lru_locks osc
11521         t0=$(date +%s)
11522
11523         can0=$(do_facet $SINGLEMDS \
11524                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11525                awk '/ldlm_cancel/ {print $2}')
11526         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11527                awk '/ldlm_bl_callback/ {print $2}')
11528         createmany -o $DIR/$tdir/f $count
11529         sync
11530         can1=$(do_facet $SINGLEMDS \
11531                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11532                awk '/ldlm_cancel/ {print $2}')
11533         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11534                awk '/ldlm_bl_callback/ {print $2}')
11535         t1=$(date +%s)
11536         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11537         echo rm $count files
11538         rm -r $DIR/$tdir
11539         sync
11540         can2=$(do_facet $SINGLEMDS \
11541                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11542                awk '/ldlm_cancel/ {print $2}')
11543         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11544                awk '/ldlm_bl_callback/ {print $2}')
11545         t2=$(date +%s)
11546         echo total: $count removes in $((t2-t1))
11547         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11548         sleep 2
11549         # wait for commitment of removal
11550         lru_resize_enable mdc
11551         lru_resize_enable osc
11552 }
11553 run_test 120g "Early Lock Cancel: performance test"
11554
11555 test_121() { #bug #10589
11556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11557
11558         rm -rf $DIR/$tfile
11559         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11560 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11561         lctl set_param fail_loc=0x310
11562         cancel_lru_locks osc > /dev/null
11563         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11564         lctl set_param fail_loc=0
11565         [[ $reads -eq $writes ]] ||
11566                 error "read $reads blocks, must be $writes blocks"
11567 }
11568 run_test 121 "read cancel race ========="
11569
11570 test_123a_base() { # was test 123, statahead(bug 11401)
11571         local lsx="$1"
11572
11573         SLOWOK=0
11574         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11575                 log "testing UP system. Performance may be lower than expected."
11576                 SLOWOK=1
11577         fi
11578
11579         rm -rf $DIR/$tdir
11580         test_mkdir $DIR/$tdir
11581         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11582         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11583         MULT=10
11584         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11585                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11586
11587                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
11588                 lctl set_param -n llite.*.statahead_max 0
11589                 lctl get_param llite.*.statahead_max
11590                 cancel_lru_locks mdc
11591                 cancel_lru_locks osc
11592                 stime=$(date +%s)
11593                 time $lsx $DIR/$tdir | wc -l
11594                 etime=$(date +%s)
11595                 delta=$((etime - stime))
11596                 log "$lsx $i files without statahead: $delta sec"
11597                 lctl set_param llite.*.statahead_max=$max
11598
11599                 swrong=$(lctl get_param -n llite.*.statahead_stats |
11600                         grep "statahead wrong:" | awk '{print $3}')
11601                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11602                 cancel_lru_locks mdc
11603                 cancel_lru_locks osc
11604                 stime=$(date +%s)
11605                 time $lsx $DIR/$tdir | wc -l
11606                 etime=$(date +%s)
11607                 delta_sa=$((etime - stime))
11608                 log "$lsx $i files with statahead: $delta_sa sec"
11609                 lctl get_param -n llite.*.statahead_stats
11610                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
11611                         grep "statahead wrong:" | awk '{print $3}')
11612
11613                 [[ $swrong -lt $ewrong ]] &&
11614                         log "statahead was stopped, maybe too many locks held!"
11615                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11616
11617                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11618                         max=$(lctl get_param -n llite.*.statahead_max |
11619                                 head -n 1)
11620                         lctl set_param -n llite.*.statahead_max 0
11621                         lctl get_param llite.*.statahead_max
11622                         cancel_lru_locks mdc
11623                         cancel_lru_locks osc
11624                         stime=$(date +%s)
11625                         time $lsx $DIR/$tdir | wc -l
11626                         etime=$(date +%s)
11627                         delta=$((etime - stime))
11628                         log "$lsx $i files again without statahead: $delta sec"
11629                         lctl set_param llite.*.statahead_max=$max
11630                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
11631                                 if [  $SLOWOK -eq 0 ]; then
11632                                         error "$lsx $i files is slower with statahead!"
11633                                 else
11634                                         log "$lsx $i files is slower with statahead!"
11635                                 fi
11636                                 break
11637                         fi
11638                 fi
11639
11640                 [ $delta -gt 20 ] && break
11641                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11642                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11643         done
11644         log "$lsx done"
11645
11646         stime=$(date +%s)
11647         rm -r $DIR/$tdir
11648         sync
11649         etime=$(date +%s)
11650         delta=$((etime - stime))
11651         log "rm -r $DIR/$tdir/: $delta seconds"
11652         log "rm done"
11653         lctl get_param -n llite.*.statahead_stats
11654 }
11655
11656 test_123aa() {
11657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11658
11659         test_123a_base "ls -l"
11660 }
11661 run_test 123aa "verify statahead work"
11662
11663 test_123ab() {
11664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11665
11666         statx_supported || skip_env "Test must be statx() syscall supported"
11667
11668         test_123a_base "$STATX -l"
11669 }
11670 run_test 123ab "verify statahead work by using statx"
11671
11672 test_123ac() {
11673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11674
11675         statx_supported || skip_env "Test must be statx() syscall supported"
11676
11677         local rpcs_before
11678         local rpcs_after
11679         local agl_before
11680         local agl_after
11681
11682         cancel_lru_locks $OSC
11683         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11684         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
11685                 awk '/agl.total:/ {print $3}')
11686         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
11687         test_123a_base "$STATX --cached=always -D"
11688         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
11689                 awk '/agl.total:/ {print $3}')
11690         [ $agl_before -eq $agl_after ] ||
11691                 error "Should not trigger AGL thread - $agl_before:$agl_after"
11692         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11693         [ $rpcs_after -eq $rpcs_before ] ||
11694                 error "$STATX should not send glimpse RPCs to $OSC"
11695 }
11696 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
11697
11698 test_123b () { # statahead(bug 15027)
11699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11700
11701         test_mkdir $DIR/$tdir
11702         createmany -o $DIR/$tdir/$tfile-%d 1000
11703
11704         cancel_lru_locks mdc
11705         cancel_lru_locks osc
11706
11707 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11708         lctl set_param fail_loc=0x80000803
11709         ls -lR $DIR/$tdir > /dev/null
11710         log "ls done"
11711         lctl set_param fail_loc=0x0
11712         lctl get_param -n llite.*.statahead_stats
11713         rm -r $DIR/$tdir
11714         sync
11715
11716 }
11717 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11718
11719 test_123c() {
11720         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11721
11722         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11723         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11724         touch $DIR/$tdir.1/{1..3}
11725         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11726
11727         remount_client $MOUNT
11728
11729         $MULTIOP $DIR/$tdir.0 Q
11730
11731         # let statahead to complete
11732         ls -l $DIR/$tdir.0 > /dev/null
11733
11734         testid=$(echo $TESTNAME | tr '_' ' ')
11735         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11736                 error "statahead warning" || true
11737 }
11738 run_test 123c "Can not initialize inode warning on DNE statahead"
11739
11740 test_124a() {
11741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11742         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11743                 skip_env "no lru resize on server"
11744
11745         local NR=2000
11746
11747         test_mkdir $DIR/$tdir
11748
11749         log "create $NR files at $DIR/$tdir"
11750         createmany -o $DIR/$tdir/f $NR ||
11751                 error "failed to create $NR files in $DIR/$tdir"
11752
11753         cancel_lru_locks mdc
11754         ls -l $DIR/$tdir > /dev/null
11755
11756         local NSDIR=""
11757         local LRU_SIZE=0
11758         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11759                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11760                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11761                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11762                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11763                         log "NSDIR=$NSDIR"
11764                         log "NS=$(basename $NSDIR)"
11765                         break
11766                 fi
11767         done
11768
11769         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11770                 skip "Not enough cached locks created!"
11771         fi
11772         log "LRU=$LRU_SIZE"
11773
11774         local SLEEP=30
11775
11776         # We know that lru resize allows one client to hold $LIMIT locks
11777         # for 10h. After that locks begin to be killed by client.
11778         local MAX_HRS=10
11779         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11780         log "LIMIT=$LIMIT"
11781         if [ $LIMIT -lt $LRU_SIZE ]; then
11782                 skip "Limit is too small $LIMIT"
11783         fi
11784
11785         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11786         # killing locks. Some time was spent for creating locks. This means
11787         # that up to the moment of sleep finish we must have killed some of
11788         # them (10-100 locks). This depends on how fast ther were created.
11789         # Many of them were touched in almost the same moment and thus will
11790         # be killed in groups.
11791         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
11792
11793         # Use $LRU_SIZE_B here to take into account real number of locks
11794         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11795         local LRU_SIZE_B=$LRU_SIZE
11796         log "LVF=$LVF"
11797         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11798         log "OLD_LVF=$OLD_LVF"
11799         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11800
11801         # Let's make sure that we really have some margin. Client checks
11802         # cached locks every 10 sec.
11803         SLEEP=$((SLEEP+20))
11804         log "Sleep ${SLEEP} sec"
11805         local SEC=0
11806         while ((SEC<$SLEEP)); do
11807                 echo -n "..."
11808                 sleep 5
11809                 SEC=$((SEC+5))
11810                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11811                 echo -n "$LRU_SIZE"
11812         done
11813         echo ""
11814         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11815         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11816
11817         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11818                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11819                 unlinkmany $DIR/$tdir/f $NR
11820                 return
11821         }
11822
11823         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11824         log "unlink $NR files at $DIR/$tdir"
11825         unlinkmany $DIR/$tdir/f $NR
11826 }
11827 run_test 124a "lru resize ======================================="
11828
11829 get_max_pool_limit()
11830 {
11831         local limit=$($LCTL get_param \
11832                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11833         local max=0
11834         for l in $limit; do
11835                 if [[ $l -gt $max ]]; then
11836                         max=$l
11837                 fi
11838         done
11839         echo $max
11840 }
11841
11842 test_124b() {
11843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11844         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11845                 skip_env "no lru resize on server"
11846
11847         LIMIT=$(get_max_pool_limit)
11848
11849         NR=$(($(default_lru_size)*20))
11850         if [[ $NR -gt $LIMIT ]]; then
11851                 log "Limit lock number by $LIMIT locks"
11852                 NR=$LIMIT
11853         fi
11854
11855         IFree=$(mdsrate_inodes_available)
11856         if [ $IFree -lt $NR ]; then
11857                 log "Limit lock number by $IFree inodes"
11858                 NR=$IFree
11859         fi
11860
11861         lru_resize_disable mdc
11862         test_mkdir -p $DIR/$tdir/disable_lru_resize
11863
11864         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11865         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11866         cancel_lru_locks mdc
11867         stime=`date +%s`
11868         PID=""
11869         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11870         PID="$PID $!"
11871         sleep 2
11872         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11873         PID="$PID $!"
11874         sleep 2
11875         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11876         PID="$PID $!"
11877         wait $PID
11878         etime=`date +%s`
11879         nolruresize_delta=$((etime-stime))
11880         log "ls -la time: $nolruresize_delta seconds"
11881         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11882         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11883
11884         lru_resize_enable mdc
11885         test_mkdir -p $DIR/$tdir/enable_lru_resize
11886
11887         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11888         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11889         cancel_lru_locks mdc
11890         stime=`date +%s`
11891         PID=""
11892         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11893         PID="$PID $!"
11894         sleep 2
11895         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11896         PID="$PID $!"
11897         sleep 2
11898         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11899         PID="$PID $!"
11900         wait $PID
11901         etime=`date +%s`
11902         lruresize_delta=$((etime-stime))
11903         log "ls -la time: $lruresize_delta seconds"
11904         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11905
11906         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11907                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11908         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11909                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11910         else
11911                 log "lru resize performs the same with no lru resize"
11912         fi
11913         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
11914 }
11915 run_test 124b "lru resize (performance test) ======================="
11916
11917 test_124c() {
11918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11919         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11920                 skip_env "no lru resize on server"
11921
11922         # cache ununsed locks on client
11923         local nr=100
11924         cancel_lru_locks mdc
11925         test_mkdir $DIR/$tdir
11926         createmany -o $DIR/$tdir/f $nr ||
11927                 error "failed to create $nr files in $DIR/$tdir"
11928         ls -l $DIR/$tdir > /dev/null
11929
11930         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11931         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11932         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11933         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11934         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11935
11936         # set lru_max_age to 1 sec
11937         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11938         echo "sleep $((recalc_p * 2)) seconds..."
11939         sleep $((recalc_p * 2))
11940
11941         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11942         # restore lru_max_age
11943         $LCTL set_param -n $nsdir.lru_max_age $max_age
11944         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11945         unlinkmany $DIR/$tdir/f $nr
11946 }
11947 run_test 124c "LRUR cancel very aged locks"
11948
11949 test_124d() {
11950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11951         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11952                 skip_env "no lru resize on server"
11953
11954         # cache ununsed locks on client
11955         local nr=100
11956
11957         lru_resize_disable mdc
11958         stack_trap "lru_resize_enable mdc" EXIT
11959
11960         cancel_lru_locks mdc
11961
11962         # asynchronous object destroy at MDT could cause bl ast to client
11963         test_mkdir $DIR/$tdir
11964         createmany -o $DIR/$tdir/f $nr ||
11965                 error "failed to create $nr files in $DIR/$tdir"
11966         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
11967
11968         ls -l $DIR/$tdir > /dev/null
11969
11970         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11971         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11972         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11973         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11974
11975         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11976
11977         # set lru_max_age to 1 sec
11978         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11979         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
11980
11981         echo "sleep $((recalc_p * 2)) seconds..."
11982         sleep $((recalc_p * 2))
11983
11984         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11985
11986         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11987 }
11988 run_test 124d "cancel very aged locks if lru-resize diasbaled"
11989
11990 test_125() { # 13358
11991         $LCTL get_param -n llite.*.client_type | grep -q local ||
11992                 skip "must run as local client"
11993         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
11994                 skip_env "must have acl enabled"
11995         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11996
11997         test_mkdir $DIR/$tdir
11998         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
11999         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12000         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12001 }
12002 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12003
12004 test_126() { # bug 12829/13455
12005         $GSS && skip_env "must run as gss disabled"
12006         $LCTL get_param -n llite.*.client_type | grep -q local ||
12007                 skip "must run as local client"
12008         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12009
12010         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12011         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12012         rm -f $DIR/$tfile
12013         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12014 }
12015 run_test 126 "check that the fsgid provided by the client is taken into account"
12016
12017 test_127a() { # bug 15521
12018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12019         local name count samp unit min max sum sumsq
12020
12021         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12022         echo "stats before reset"
12023         $LCTL get_param osc.*.stats
12024         $LCTL set_param osc.*.stats=0
12025         local fsize=$((2048 * 1024))
12026
12027         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12028         cancel_lru_locks osc
12029         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12030
12031         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12032         stack_trap "rm -f $TMP/$tfile.tmp"
12033         while read name count samp unit min max sum sumsq; do
12034                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12035                 [ ! $min ] && error "Missing min value for $name proc entry"
12036                 eval $name=$count || error "Wrong proc format"
12037
12038                 case $name in
12039                 read_bytes|write_bytes)
12040                         [[ "$unit" =~ "bytes" ]] ||
12041                                 error "unit is not 'bytes': $unit"
12042                         (( $min >= 4096 )) || error "min is too small: $min"
12043                         (( $min <= $fsize )) || error "min is too big: $min"
12044                         (( $max >= 4096 )) || error "max is too small: $max"
12045                         (( $max <= $fsize )) || error "max is too big: $max"
12046                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12047                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12048                                 error "sumsquare is too small: $sumsq"
12049                         (( $sumsq <= $fsize * $fsize )) ||
12050                                 error "sumsquare is too big: $sumsq"
12051                         ;;
12052                 ost_read|ost_write)
12053                         [[ "$unit" =~ "usec" ]] ||
12054                                 error "unit is not 'usec': $unit"
12055                         ;;
12056                 *)      ;;
12057                 esac
12058         done < $DIR/$tfile.tmp
12059
12060         #check that we actually got some stats
12061         [ "$read_bytes" ] || error "Missing read_bytes stats"
12062         [ "$write_bytes" ] || error "Missing write_bytes stats"
12063         [ "$read_bytes" != 0 ] || error "no read done"
12064         [ "$write_bytes" != 0 ] || error "no write done"
12065 }
12066 run_test 127a "verify the client stats are sane"
12067
12068 test_127b() { # bug LU-333
12069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12070         local name count samp unit min max sum sumsq
12071
12072         echo "stats before reset"
12073         $LCTL get_param llite.*.stats
12074         $LCTL set_param llite.*.stats=0
12075
12076         # perform 2 reads and writes so MAX is different from SUM.
12077         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12078         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12079         cancel_lru_locks osc
12080         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12081         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12082
12083         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12084         stack_trap "rm -f $TMP/$tfile.tmp"
12085         while read name count samp unit min max sum sumsq; do
12086                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12087                 eval $name=$count || error "Wrong proc format"
12088
12089                 case $name in
12090                 read_bytes|write_bytes)
12091                         [[ "$unit" =~ "bytes" ]] ||
12092                                 error "unit is not 'bytes': $unit"
12093                         (( $count == 2 )) || error "count is not 2: $count"
12094                         (( $min == $PAGE_SIZE )) ||
12095                                 error "min is not $PAGE_SIZE: $min"
12096                         (( $max == $PAGE_SIZE )) ||
12097                                 error "max is not $PAGE_SIZE: $max"
12098                         (( $sum == $PAGE_SIZE * 2 )) ||
12099                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12100                         ;;
12101                 read|write)
12102                         [[ "$unit" =~ "usec" ]] ||
12103                                 error "unit is not 'usec': $unit"
12104                         ;;
12105                 *)      ;;
12106                 esac
12107         done < $TMP/$tfile.tmp
12108
12109         #check that we actually got some stats
12110         [ "$read_bytes" ] || error "Missing read_bytes stats"
12111         [ "$write_bytes" ] || error "Missing write_bytes stats"
12112         [ "$read_bytes" != 0 ] || error "no read done"
12113         [ "$write_bytes" != 0 ] || error "no write done"
12114 }
12115 run_test 127b "verify the llite client stats are sane"
12116
12117 test_127c() { # LU-12394
12118         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12119         local size
12120         local bsize
12121         local reads
12122         local writes
12123         local count
12124
12125         $LCTL set_param llite.*.extents_stats=1
12126         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12127
12128         # Use two stripes so there is enough space in default config
12129         $LFS setstripe -c 2 $DIR/$tfile
12130
12131         # Extent stats start at 0-4K and go in power of two buckets
12132         # LL_HIST_START = 12 --> 2^12 = 4K
12133         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12134         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12135         # small configs
12136         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12137                 do
12138                 # Write and read, 2x each, second time at a non-zero offset
12139                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12140                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12141                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12142                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12143                 rm -f $DIR/$tfile
12144         done
12145
12146         $LCTL get_param llite.*.extents_stats
12147
12148         count=2
12149         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12150                 do
12151                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12152                                 grep -m 1 $bsize)
12153                 reads=$(echo $bucket | awk '{print $5}')
12154                 writes=$(echo $bucket | awk '{print $9}')
12155                 [ "$reads" -eq $count ] ||
12156                         error "$reads reads in < $bsize bucket, expect $count"
12157                 [ "$writes" -eq $count ] ||
12158                         error "$writes writes in < $bsize bucket, expect $count"
12159         done
12160
12161         # Test mmap write and read
12162         $LCTL set_param llite.*.extents_stats=c
12163         size=512
12164         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12165         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12166         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12167
12168         $LCTL get_param llite.*.extents_stats
12169
12170         count=$(((size*1024) / PAGE_SIZE))
12171
12172         bsize=$((2 * PAGE_SIZE / 1024))K
12173
12174         bucket=$($LCTL get_param -n llite.*.extents_stats |
12175                         grep -m 1 $bsize)
12176         reads=$(echo $bucket | awk '{print $5}')
12177         writes=$(echo $bucket | awk '{print $9}')
12178         # mmap writes fault in the page first, creating an additonal read
12179         [ "$reads" -eq $((2 * count)) ] ||
12180                 error "$reads reads in < $bsize bucket, expect $count"
12181         [ "$writes" -eq $count ] ||
12182                 error "$writes writes in < $bsize bucket, expect $count"
12183 }
12184 run_test 127c "test llite extent stats with regular & mmap i/o"
12185
12186 test_128() { # bug 15212
12187         touch $DIR/$tfile
12188         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12189                 find $DIR/$tfile
12190                 find $DIR/$tfile
12191         EOF
12192
12193         result=$(grep error $TMP/$tfile.log)
12194         rm -f $DIR/$tfile $TMP/$tfile.log
12195         [ -z "$result" ] ||
12196                 error "consecutive find's under interactive lfs failed"
12197 }
12198 run_test 128 "interactive lfs for 2 consecutive find's"
12199
12200 set_dir_limits () {
12201         local mntdev
12202         local canondev
12203         local node
12204
12205         local ldproc=/proc/fs/ldiskfs
12206         local facets=$(get_facets MDS)
12207
12208         for facet in ${facets//,/ }; do
12209                 canondev=$(ldiskfs_canon \
12210                            *.$(convert_facet2label $facet).mntdev $facet)
12211                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12212                         ldproc=/sys/fs/ldiskfs
12213                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12214                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12215         done
12216 }
12217
12218 check_mds_dmesg() {
12219         local facets=$(get_facets MDS)
12220         for facet in ${facets//,/ }; do
12221                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12222         done
12223         return 1
12224 }
12225
12226 test_129() {
12227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12228         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12229                 skip "Need MDS version with at least 2.5.56"
12230         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12231                 skip_env "ldiskfs only test"
12232         fi
12233         remote_mds_nodsh && skip "remote MDS with nodsh"
12234
12235         local ENOSPC=28
12236         local has_warning=false
12237
12238         rm -rf $DIR/$tdir
12239         mkdir -p $DIR/$tdir
12240
12241         # block size of mds1
12242         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12243         set_dir_limits $maxsize $((maxsize * 6 / 8))
12244         stack_trap "set_dir_limits 0 0"
12245         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12246         local dirsize=$(stat -c%s "$DIR/$tdir")
12247         local nfiles=0
12248         while (( $dirsize <= $maxsize )); do
12249                 $MCREATE $DIR/$tdir/file_base_$nfiles
12250                 rc=$?
12251                 # check two errors:
12252                 # ENOSPC for ext4 max_dir_size, which has been used since
12253                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12254                 if (( rc == ENOSPC )); then
12255                         set_dir_limits 0 0
12256                         echo "rc=$rc returned as expected after $nfiles files"
12257
12258                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12259                                 error "create failed w/o dir size limit"
12260
12261                         # messages may be rate limited if test is run repeatedly
12262                         check_mds_dmesg '"is approaching max"' ||
12263                                 echo "warning message should be output"
12264                         check_mds_dmesg '"has reached max"' ||
12265                                 echo "reached message should be output"
12266
12267                         dirsize=$(stat -c%s "$DIR/$tdir")
12268
12269                         [[ $dirsize -ge $maxsize ]] && return 0
12270                         error "dirsize $dirsize < $maxsize after $nfiles files"
12271                 elif (( rc != 0 )); then
12272                         break
12273                 fi
12274                 nfiles=$((nfiles + 1))
12275                 dirsize=$(stat -c%s "$DIR/$tdir")
12276         done
12277
12278         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12279 }
12280 run_test 129 "test directory size limit ========================"
12281
12282 OLDIFS="$IFS"
12283 cleanup_130() {
12284         trap 0
12285         IFS="$OLDIFS"
12286 }
12287
12288 test_130a() {
12289         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12290         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12291
12292         trap cleanup_130 EXIT RETURN
12293
12294         local fm_file=$DIR/$tfile
12295         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12296         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12297                 error "dd failed for $fm_file"
12298
12299         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12300         filefrag -ves $fm_file
12301         RC=$?
12302         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12303                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12304         [ $RC != 0 ] && error "filefrag $fm_file failed"
12305
12306         filefrag_op=$(filefrag -ve -k $fm_file |
12307                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12308         lun=$($LFS getstripe -i $fm_file)
12309
12310         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12311         IFS=$'\n'
12312         tot_len=0
12313         for line in $filefrag_op
12314         do
12315                 frag_lun=`echo $line | cut -d: -f5`
12316                 ext_len=`echo $line | cut -d: -f4`
12317                 if (( $frag_lun != $lun )); then
12318                         cleanup_130
12319                         error "FIEMAP on 1-stripe file($fm_file) failed"
12320                         return
12321                 fi
12322                 (( tot_len += ext_len ))
12323         done
12324
12325         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12326                 cleanup_130
12327                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12328                 return
12329         fi
12330
12331         cleanup_130
12332
12333         echo "FIEMAP on single striped file succeeded"
12334 }
12335 run_test 130a "FIEMAP (1-stripe file)"
12336
12337 test_130b() {
12338         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12339
12340         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12341         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12342
12343         trap cleanup_130 EXIT RETURN
12344
12345         local fm_file=$DIR/$tfile
12346         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12347                         error "setstripe on $fm_file"
12348         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12349                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12350
12351         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12352                 error "dd failed on $fm_file"
12353
12354         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12355         filefrag_op=$(filefrag -ve -k $fm_file |
12356                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12357
12358         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12359                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12360
12361         IFS=$'\n'
12362         tot_len=0
12363         num_luns=1
12364         for line in $filefrag_op
12365         do
12366                 frag_lun=$(echo $line | cut -d: -f5 |
12367                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12368                 ext_len=$(echo $line | cut -d: -f4)
12369                 if (( $frag_lun != $last_lun )); then
12370                         if (( tot_len != 1024 )); then
12371                                 cleanup_130
12372                                 error "FIEMAP on $fm_file failed; returned " \
12373                                 "len $tot_len for OST $last_lun instead of 1024"
12374                                 return
12375                         else
12376                                 (( num_luns += 1 ))
12377                                 tot_len=0
12378                         fi
12379                 fi
12380                 (( tot_len += ext_len ))
12381                 last_lun=$frag_lun
12382         done
12383         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12384                 cleanup_130
12385                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12386                         "luns or wrong len for OST $last_lun"
12387                 return
12388         fi
12389
12390         cleanup_130
12391
12392         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12393 }
12394 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12395
12396 test_130c() {
12397         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12398
12399         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12400         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12401
12402         trap cleanup_130 EXIT RETURN
12403
12404         local fm_file=$DIR/$tfile
12405         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12406         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12407                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12408
12409         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12410                         error "dd failed on $fm_file"
12411
12412         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12413         filefrag_op=$(filefrag -ve -k $fm_file |
12414                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12415
12416         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12417                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12418
12419         IFS=$'\n'
12420         tot_len=0
12421         num_luns=1
12422         for line in $filefrag_op
12423         do
12424                 frag_lun=$(echo $line | cut -d: -f5 |
12425                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12426                 ext_len=$(echo $line | cut -d: -f4)
12427                 if (( $frag_lun != $last_lun )); then
12428                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12429                         if (( logical != 512 )); then
12430                                 cleanup_130
12431                                 error "FIEMAP on $fm_file failed; returned " \
12432                                 "logical start for lun $logical instead of 512"
12433                                 return
12434                         fi
12435                         if (( tot_len != 512 )); then
12436                                 cleanup_130
12437                                 error "FIEMAP on $fm_file failed; returned " \
12438                                 "len $tot_len for OST $last_lun instead of 1024"
12439                                 return
12440                         else
12441                                 (( num_luns += 1 ))
12442                                 tot_len=0
12443                         fi
12444                 fi
12445                 (( tot_len += ext_len ))
12446                 last_lun=$frag_lun
12447         done
12448         if (( num_luns != 2 || tot_len != 512 )); then
12449                 cleanup_130
12450                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12451                         "luns or wrong len for OST $last_lun"
12452                 return
12453         fi
12454
12455         cleanup_130
12456
12457         echo "FIEMAP on 2-stripe file with hole succeeded"
12458 }
12459 run_test 130c "FIEMAP (2-stripe file with hole)"
12460
12461 test_130d() {
12462         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12463
12464         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12465         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12466
12467         trap cleanup_130 EXIT RETURN
12468
12469         local fm_file=$DIR/$tfile
12470         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12471                         error "setstripe on $fm_file"
12472         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12473                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12474
12475         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12476         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12477                 error "dd failed on $fm_file"
12478
12479         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12480         filefrag_op=$(filefrag -ve -k $fm_file |
12481                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12482
12483         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12484                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12485
12486         IFS=$'\n'
12487         tot_len=0
12488         num_luns=1
12489         for line in $filefrag_op
12490         do
12491                 frag_lun=$(echo $line | cut -d: -f5 |
12492                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12493                 ext_len=$(echo $line | cut -d: -f4)
12494                 if (( $frag_lun != $last_lun )); then
12495                         if (( tot_len != 1024 )); then
12496                                 cleanup_130
12497                                 error "FIEMAP on $fm_file failed; returned " \
12498                                 "len $tot_len for OST $last_lun instead of 1024"
12499                                 return
12500                         else
12501                                 (( num_luns += 1 ))
12502                                 tot_len=0
12503                         fi
12504                 fi
12505                 (( tot_len += ext_len ))
12506                 last_lun=$frag_lun
12507         done
12508         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12509                 cleanup_130
12510                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12511                         "luns or wrong len for OST $last_lun"
12512                 return
12513         fi
12514
12515         cleanup_130
12516
12517         echo "FIEMAP on N-stripe file succeeded"
12518 }
12519 run_test 130d "FIEMAP (N-stripe file)"
12520
12521 test_130e() {
12522         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12523
12524         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12525         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12526
12527         trap cleanup_130 EXIT RETURN
12528
12529         local fm_file=$DIR/$tfile
12530         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12531         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12532                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12533
12534         NUM_BLKS=512
12535         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12536         for ((i = 0; i < $NUM_BLKS; i++))
12537         do
12538                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
12539         done
12540
12541         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12542         filefrag_op=$(filefrag -ve -k $fm_file |
12543                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12544
12545         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12546                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12547
12548         IFS=$'\n'
12549         tot_len=0
12550         num_luns=1
12551         for line in $filefrag_op
12552         do
12553                 frag_lun=$(echo $line | cut -d: -f5 |
12554                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12555                 ext_len=$(echo $line | cut -d: -f4)
12556                 if (( $frag_lun != $last_lun )); then
12557                         if (( tot_len != $EXPECTED_LEN )); then
12558                                 cleanup_130
12559                                 error "FIEMAP on $fm_file failed; returned " \
12560                                 "len $tot_len for OST $last_lun instead " \
12561                                 "of $EXPECTED_LEN"
12562                                 return
12563                         else
12564                                 (( num_luns += 1 ))
12565                                 tot_len=0
12566                         fi
12567                 fi
12568                 (( tot_len += ext_len ))
12569                 last_lun=$frag_lun
12570         done
12571         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12572                 cleanup_130
12573                 error "FIEMAP on $fm_file failed; returned wrong number " \
12574                         "of luns or wrong len for OST $last_lun"
12575                 return
12576         fi
12577
12578         cleanup_130
12579
12580         echo "FIEMAP with continuation calls succeeded"
12581 }
12582 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12583
12584 test_130f() {
12585         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12586         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12587
12588         local fm_file=$DIR/$tfile
12589         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12590                 error "multiop create with lov_delay_create on $fm_file"
12591
12592         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12593         filefrag_extents=$(filefrag -vek $fm_file |
12594                            awk '/extents? found/ { print $2 }')
12595         if [[ "$filefrag_extents" != "0" ]]; then
12596                 error "FIEMAP on $fm_file failed; " \
12597                       "returned $filefrag_extents expected 0"
12598         fi
12599
12600         rm -f $fm_file
12601 }
12602 run_test 130f "FIEMAP (unstriped file)"
12603
12604 # Test for writev/readv
12605 test_131a() {
12606         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12607                 error "writev test failed"
12608         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12609                 error "readv failed"
12610         rm -f $DIR/$tfile
12611 }
12612 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12613
12614 test_131b() {
12615         local fsize=$((524288 + 1048576 + 1572864))
12616         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12617                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12618                         error "append writev test failed"
12619
12620         ((fsize += 1572864 + 1048576))
12621         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12622                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12623                         error "append writev test failed"
12624         rm -f $DIR/$tfile
12625 }
12626 run_test 131b "test append writev"
12627
12628 test_131c() {
12629         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12630         error "NOT PASS"
12631 }
12632 run_test 131c "test read/write on file w/o objects"
12633
12634 test_131d() {
12635         rwv -f $DIR/$tfile -w -n 1 1572864
12636         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12637         if [ "$NOB" != 1572864 ]; then
12638                 error "Short read filed: read $NOB bytes instead of 1572864"
12639         fi
12640         rm -f $DIR/$tfile
12641 }
12642 run_test 131d "test short read"
12643
12644 test_131e() {
12645         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12646         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12647         error "read hitting hole failed"
12648         rm -f $DIR/$tfile
12649 }
12650 run_test 131e "test read hitting hole"
12651
12652 check_stats() {
12653         local facet=$1
12654         local op=$2
12655         local want=${3:-0}
12656         local res
12657
12658         case $facet in
12659         mds*) res=$(do_facet $facet \
12660                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12661                  ;;
12662         ost*) res=$(do_facet $facet \
12663                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12664                  ;;
12665         *) error "Wrong facet '$facet'" ;;
12666         esac
12667         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12668         # if the argument $3 is zero, it means any stat increment is ok.
12669         if [[ $want -gt 0 ]]; then
12670                 local count=$(echo $res | awk '{ print $2 }')
12671                 [[ $count -ne $want ]] &&
12672                         error "The $op counter on $facet is $count, not $want"
12673         fi
12674 }
12675
12676 test_133a() {
12677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12678         remote_ost_nodsh && skip "remote OST with nodsh"
12679         remote_mds_nodsh && skip "remote MDS with nodsh"
12680         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12681                 skip_env "MDS doesn't support rename stats"
12682
12683         local testdir=$DIR/${tdir}/stats_testdir
12684
12685         mkdir -p $DIR/${tdir}
12686
12687         # clear stats.
12688         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12689         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12690
12691         # verify mdt stats first.
12692         mkdir ${testdir} || error "mkdir failed"
12693         check_stats $SINGLEMDS "mkdir" 1
12694         touch ${testdir}/${tfile} || error "touch failed"
12695         check_stats $SINGLEMDS "open" 1
12696         check_stats $SINGLEMDS "close" 1
12697         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12698                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12699                 check_stats $SINGLEMDS "mknod" 2
12700         }
12701         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12702         check_stats $SINGLEMDS "unlink" 1
12703         rm -f ${testdir}/${tfile} || error "file remove failed"
12704         check_stats $SINGLEMDS "unlink" 2
12705
12706         # remove working dir and check mdt stats again.
12707         rmdir ${testdir} || error "rmdir failed"
12708         check_stats $SINGLEMDS "rmdir" 1
12709
12710         local testdir1=$DIR/${tdir}/stats_testdir1
12711         mkdir -p ${testdir}
12712         mkdir -p ${testdir1}
12713         touch ${testdir1}/test1
12714         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12715         check_stats $SINGLEMDS "crossdir_rename" 1
12716
12717         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12718         check_stats $SINGLEMDS "samedir_rename" 1
12719
12720         rm -rf $DIR/${tdir}
12721 }
12722 run_test 133a "Verifying MDT stats ========================================"
12723
12724 test_133b() {
12725         local res
12726
12727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12728         remote_ost_nodsh && skip "remote OST with nodsh"
12729         remote_mds_nodsh && skip "remote MDS with nodsh"
12730
12731         local testdir=$DIR/${tdir}/stats_testdir
12732
12733         mkdir -p ${testdir} || error "mkdir failed"
12734         touch ${testdir}/${tfile} || error "touch failed"
12735         cancel_lru_locks mdc
12736
12737         # clear stats.
12738         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12739         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12740
12741         # extra mdt stats verification.
12742         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12743         check_stats $SINGLEMDS "setattr" 1
12744         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12745         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12746         then            # LU-1740
12747                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12748                 check_stats $SINGLEMDS "getattr" 1
12749         fi
12750         rm -rf $DIR/${tdir}
12751
12752         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12753         # so the check below is not reliable
12754         [ $MDSCOUNT -eq 1 ] || return 0
12755
12756         # Sleep to avoid a cached response.
12757         #define OBD_STATFS_CACHE_SECONDS 1
12758         sleep 2
12759         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12760         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12761         $LFS df || error "lfs failed"
12762         check_stats $SINGLEMDS "statfs" 1
12763
12764         # check aggregated statfs (LU-10018)
12765         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12766                 return 0
12767         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12768                 return 0
12769         sleep 2
12770         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12771         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12772         df $DIR
12773         check_stats $SINGLEMDS "statfs" 1
12774
12775         # We want to check that the client didn't send OST_STATFS to
12776         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12777         # extra care is needed here.
12778         if remote_mds; then
12779                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12780                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12781
12782                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12783                 [ "$res" ] && error "OST got STATFS"
12784         fi
12785
12786         return 0
12787 }
12788 run_test 133b "Verifying extra MDT stats =================================="
12789
12790 test_133c() {
12791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12792         remote_ost_nodsh && skip "remote OST with nodsh"
12793         remote_mds_nodsh && skip "remote MDS with nodsh"
12794
12795         local testdir=$DIR/$tdir/stats_testdir
12796
12797         test_mkdir -p $testdir
12798
12799         # verify obdfilter stats.
12800         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12801         sync
12802         cancel_lru_locks osc
12803         wait_delete_completed
12804
12805         # clear stats.
12806         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12807         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12808
12809         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12810                 error "dd failed"
12811         sync
12812         cancel_lru_locks osc
12813         check_stats ost1 "write" 1
12814
12815         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12816         check_stats ost1 "read" 1
12817
12818         > $testdir/$tfile || error "truncate failed"
12819         check_stats ost1 "punch" 1
12820
12821         rm -f $testdir/$tfile || error "file remove failed"
12822         wait_delete_completed
12823         check_stats ost1 "destroy" 1
12824
12825         rm -rf $DIR/$tdir
12826 }
12827 run_test 133c "Verifying OST stats ========================================"
12828
12829 order_2() {
12830         local value=$1
12831         local orig=$value
12832         local order=1
12833
12834         while [ $value -ge 2 ]; do
12835                 order=$((order*2))
12836                 value=$((value/2))
12837         done
12838
12839         if [ $orig -gt $order ]; then
12840                 order=$((order*2))
12841         fi
12842         echo $order
12843 }
12844
12845 size_in_KMGT() {
12846     local value=$1
12847     local size=('K' 'M' 'G' 'T');
12848     local i=0
12849     local size_string=$value
12850
12851     while [ $value -ge 1024 ]; do
12852         if [ $i -gt 3 ]; then
12853             #T is the biggest unit we get here, if that is bigger,
12854             #just return XXXT
12855             size_string=${value}T
12856             break
12857         fi
12858         value=$((value >> 10))
12859         if [ $value -lt 1024 ]; then
12860             size_string=${value}${size[$i]}
12861             break
12862         fi
12863         i=$((i + 1))
12864     done
12865
12866     echo $size_string
12867 }
12868
12869 get_rename_size() {
12870         local size=$1
12871         local context=${2:-.}
12872         local sample=$(do_facet $SINGLEMDS $LCTL \
12873                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12874                 grep -A1 $context |
12875                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12876         echo $sample
12877 }
12878
12879 test_133d() {
12880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12881         remote_ost_nodsh && skip "remote OST with nodsh"
12882         remote_mds_nodsh && skip "remote MDS with nodsh"
12883         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12884                 skip_env "MDS doesn't support rename stats"
12885
12886         local testdir1=$DIR/${tdir}/stats_testdir1
12887         local testdir2=$DIR/${tdir}/stats_testdir2
12888         mkdir -p $DIR/${tdir}
12889
12890         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12891
12892         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12893         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12894
12895         createmany -o $testdir1/test 512 || error "createmany failed"
12896
12897         # check samedir rename size
12898         mv ${testdir1}/test0 ${testdir1}/test_0
12899
12900         local testdir1_size=$(ls -l $DIR/${tdir} |
12901                 awk '/stats_testdir1/ {print $5}')
12902         local testdir2_size=$(ls -l $DIR/${tdir} |
12903                 awk '/stats_testdir2/ {print $5}')
12904
12905         testdir1_size=$(order_2 $testdir1_size)
12906         testdir2_size=$(order_2 $testdir2_size)
12907
12908         testdir1_size=$(size_in_KMGT $testdir1_size)
12909         testdir2_size=$(size_in_KMGT $testdir2_size)
12910
12911         echo "source rename dir size: ${testdir1_size}"
12912         echo "target rename dir size: ${testdir2_size}"
12913
12914         local cmd="do_facet $SINGLEMDS $LCTL "
12915         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
12916
12917         eval $cmd || error "$cmd failed"
12918         local samedir=$($cmd | grep 'same_dir')
12919         local same_sample=$(get_rename_size $testdir1_size)
12920         [ -z "$samedir" ] && error "samedir_rename_size count error"
12921         [[ $same_sample -eq 1 ]] ||
12922                 error "samedir_rename_size error $same_sample"
12923         echo "Check same dir rename stats success"
12924
12925         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12926
12927         # check crossdir rename size
12928         mv ${testdir1}/test_0 ${testdir2}/test_0
12929
12930         testdir1_size=$(ls -l $DIR/${tdir} |
12931                 awk '/stats_testdir1/ {print $5}')
12932         testdir2_size=$(ls -l $DIR/${tdir} |
12933                 awk '/stats_testdir2/ {print $5}')
12934
12935         testdir1_size=$(order_2 $testdir1_size)
12936         testdir2_size=$(order_2 $testdir2_size)
12937
12938         testdir1_size=$(size_in_KMGT $testdir1_size)
12939         testdir2_size=$(size_in_KMGT $testdir2_size)
12940
12941         echo "source rename dir size: ${testdir1_size}"
12942         echo "target rename dir size: ${testdir2_size}"
12943
12944         eval $cmd || error "$cmd failed"
12945         local crossdir=$($cmd | grep 'crossdir')
12946         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
12947         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
12948         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
12949         [[ $src_sample -eq 1 ]] ||
12950                 error "crossdir_rename_size error $src_sample"
12951         [[ $tgt_sample -eq 1 ]] ||
12952                 error "crossdir_rename_size error $tgt_sample"
12953         echo "Check cross dir rename stats success"
12954         rm -rf $DIR/${tdir}
12955 }
12956 run_test 133d "Verifying rename_stats ========================================"
12957
12958 test_133e() {
12959         remote_mds_nodsh && skip "remote MDS with nodsh"
12960         remote_ost_nodsh && skip "remote OST with nodsh"
12961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12962
12963         local testdir=$DIR/${tdir}/stats_testdir
12964         local ctr f0 f1 bs=32768 count=42 sum
12965
12966         mkdir -p ${testdir} || error "mkdir failed"
12967
12968         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
12969
12970         for ctr in {write,read}_bytes; do
12971                 sync
12972                 cancel_lru_locks osc
12973
12974                 do_facet ost1 $LCTL set_param -n \
12975                         "obdfilter.*.exports.clear=clear"
12976
12977                 if [ $ctr = write_bytes ]; then
12978                         f0=/dev/zero
12979                         f1=${testdir}/${tfile}
12980                 else
12981                         f0=${testdir}/${tfile}
12982                         f1=/dev/null
12983                 fi
12984
12985                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
12986                         error "dd failed"
12987                 sync
12988                 cancel_lru_locks osc
12989
12990                 sum=$(do_facet ost1 $LCTL get_param \
12991                         "obdfilter.*.exports.*.stats" |
12992                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
12993                                 $1 == ctr { sum += $7 }
12994                                 END { printf("%0.0f", sum) }')
12995
12996                 if ((sum != bs * count)); then
12997                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
12998                 fi
12999         done
13000
13001         rm -rf $DIR/${tdir}
13002 }
13003 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13004
13005 test_133f() {
13006         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13007                 skip "too old lustre for get_param -R ($facet_ver)"
13008
13009         # verifying readability.
13010         $LCTL get_param -R '*' &> /dev/null
13011
13012         # Verifing writability with badarea_io.
13013         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13014                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13015                 error "client badarea_io failed"
13016
13017         # remount the FS in case writes/reads /proc break the FS
13018         cleanup || error "failed to unmount"
13019         setup || error "failed to setup"
13020 }
13021 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13022
13023 test_133g() {
13024         remote_mds_nodsh && skip "remote MDS with nodsh"
13025         remote_ost_nodsh && skip "remote OST with nodsh"
13026
13027         local facet
13028         for facet in mds1 ost1; do
13029                 local facet_ver=$(lustre_version_code $facet)
13030                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13031                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13032                 else
13033                         log "$facet: too old lustre for get_param -R"
13034                 fi
13035                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13036                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13037                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13038                                 xargs badarea_io" ||
13039                                         error "$facet badarea_io failed"
13040                 else
13041                         skip_noexit "$facet: too old lustre for get_param -R"
13042                 fi
13043         done
13044
13045         # remount the FS in case writes/reads /proc break the FS
13046         cleanup || error "failed to unmount"
13047         setup || error "failed to setup"
13048 }
13049 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13050
13051 test_133h() {
13052         remote_mds_nodsh && skip "remote MDS with nodsh"
13053         remote_ost_nodsh && skip "remote OST with nodsh"
13054         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13055                 skip "Need MDS version at least 2.9.54"
13056
13057         local facet
13058         for facet in client mds1 ost1; do
13059                 # Get the list of files that are missing the terminating newline
13060                 local plist=$(do_facet $facet
13061                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13062                 local ent
13063                 for ent in $plist; do
13064                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13065                                 awk -v FS='\v' -v RS='\v\v' \
13066                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13067                                         print FILENAME}'" 2>/dev/null)
13068                         [ -z $missing ] || {
13069                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13070                                 error "file does not end with newline: $facet-$ent"
13071                         }
13072                 done
13073         done
13074 }
13075 run_test 133h "Proc files should end with newlines"
13076
13077 test_134a() {
13078         remote_mds_nodsh && skip "remote MDS with nodsh"
13079         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13080                 skip "Need MDS version at least 2.7.54"
13081
13082         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13083         cancel_lru_locks mdc
13084
13085         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13086         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13087         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13088
13089         local nr=1000
13090         createmany -o $DIR/$tdir/f $nr ||
13091                 error "failed to create $nr files in $DIR/$tdir"
13092         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13093
13094         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13095         do_facet mds1 $LCTL set_param fail_loc=0x327
13096         do_facet mds1 $LCTL set_param fail_val=500
13097         touch $DIR/$tdir/m
13098
13099         echo "sleep 10 seconds ..."
13100         sleep 10
13101         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13102
13103         do_facet mds1 $LCTL set_param fail_loc=0
13104         do_facet mds1 $LCTL set_param fail_val=0
13105         [ $lck_cnt -lt $unused ] ||
13106                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13107
13108         rm $DIR/$tdir/m
13109         unlinkmany $DIR/$tdir/f $nr
13110 }
13111 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13112
13113 test_134b() {
13114         remote_mds_nodsh && skip "remote MDS with nodsh"
13115         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13116                 skip "Need MDS version at least 2.7.54"
13117
13118         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13119         cancel_lru_locks mdc
13120
13121         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13122                         ldlm.lock_reclaim_threshold_mb)
13123         # disable reclaim temporarily
13124         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13125
13126         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13127         do_facet mds1 $LCTL set_param fail_loc=0x328
13128         do_facet mds1 $LCTL set_param fail_val=500
13129
13130         $LCTL set_param debug=+trace
13131
13132         local nr=600
13133         createmany -o $DIR/$tdir/f $nr &
13134         local create_pid=$!
13135
13136         echo "Sleep $TIMEOUT seconds ..."
13137         sleep $TIMEOUT
13138         if ! ps -p $create_pid  > /dev/null 2>&1; then
13139                 do_facet mds1 $LCTL set_param fail_loc=0
13140                 do_facet mds1 $LCTL set_param fail_val=0
13141                 do_facet mds1 $LCTL set_param \
13142                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13143                 error "createmany finished incorrectly!"
13144         fi
13145         do_facet mds1 $LCTL set_param fail_loc=0
13146         do_facet mds1 $LCTL set_param fail_val=0
13147         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13148         wait $create_pid || return 1
13149
13150         unlinkmany $DIR/$tdir/f $nr
13151 }
13152 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13153
13154 test_135() {
13155         remote_mds_nodsh && skip "remote MDS with nodsh"
13156         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13157                 skip "Need MDS version at least 2.13.50"
13158         local fname
13159
13160         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13161
13162 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13163         #set only one record at plain llog
13164         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13165
13166         #fill already existed plain llog each 64767
13167         #wrapping whole catalog
13168         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13169
13170         createmany -o $DIR/$tdir/$tfile_ 64700
13171         for (( i = 0; i < 64700; i = i + 2 ))
13172         do
13173                 rm $DIR/$tdir/$tfile_$i &
13174                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13175                 local pid=$!
13176                 wait $pid
13177         done
13178
13179         #waiting osp synchronization
13180         wait_delete_completed
13181 }
13182 run_test 135 "Race catalog processing"
13183
13184 test_136() {
13185         remote_mds_nodsh && skip "remote MDS with nodsh"
13186         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13187                 skip "Need MDS version at least 2.13.50"
13188         local fname
13189
13190         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13191         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13192         #set only one record at plain llog
13193 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13194         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13195
13196         #fill already existed 2 plain llogs each 64767
13197         #wrapping whole catalog
13198         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13199         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13200         wait_delete_completed
13201
13202         createmany -o $DIR/$tdir/$tfile_ 10
13203         sleep 25
13204
13205         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13206         for (( i = 0; i < 10; i = i + 3 ))
13207         do
13208                 rm $DIR/$tdir/$tfile_$i &
13209                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13210                 local pid=$!
13211                 wait $pid
13212                 sleep 7
13213                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13214         done
13215
13216         #waiting osp synchronization
13217         wait_delete_completed
13218 }
13219 run_test 136 "Race catalog processing 2"
13220
13221 test_140() { #bug-17379
13222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13223
13224         test_mkdir $DIR/$tdir
13225         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13226         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13227
13228         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13229         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13230         local i=0
13231         while i=$((i + 1)); do
13232                 test_mkdir $i
13233                 cd $i || error "Changing to $i"
13234                 ln -s ../stat stat || error "Creating stat symlink"
13235                 # Read the symlink until ELOOP present,
13236                 # not LBUGing the system is considered success,
13237                 # we didn't overrun the stack.
13238                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13239                 if [ $ret -ne 0 ]; then
13240                         if [ $ret -eq 40 ]; then
13241                                 break  # -ELOOP
13242                         else
13243                                 error "Open stat symlink"
13244                                         return
13245                         fi
13246                 fi
13247         done
13248         i=$((i - 1))
13249         echo "The symlink depth = $i"
13250         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13251                 error "Invalid symlink depth"
13252
13253         # Test recursive symlink
13254         ln -s symlink_self symlink_self
13255         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13256         echo "open symlink_self returns $ret"
13257         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13258 }
13259 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13260
13261 test_150a() {
13262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13263
13264         local TF="$TMP/$tfile"
13265
13266         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13267         cp $TF $DIR/$tfile
13268         cancel_lru_locks $OSC
13269         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13270         remount_client $MOUNT
13271         df -P $MOUNT
13272         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13273
13274         $TRUNCATE $TF 6000
13275         $TRUNCATE $DIR/$tfile 6000
13276         cancel_lru_locks $OSC
13277         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13278
13279         echo "12345" >>$TF
13280         echo "12345" >>$DIR/$tfile
13281         cancel_lru_locks $OSC
13282         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13283
13284         echo "12345" >>$TF
13285         echo "12345" >>$DIR/$tfile
13286         cancel_lru_locks $OSC
13287         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13288
13289         rm -f $TF
13290         true
13291 }
13292 run_test 150a "truncate/append tests"
13293
13294 test_150b() {
13295         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13296         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13297                 skip "Need OST version at least 2.13.53"
13298         touch $DIR/$tfile
13299         check_fallocate $DIR/$tfile || error "fallocate failed"
13300 }
13301 run_test 150b "Verify fallocate (prealloc) functionality"
13302
13303 test_150c() {
13304         local bytes
13305         local want
13306
13307         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13308         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13309                 skip "Need OST version at least 2.13.53"
13310
13311         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13312         fallocate -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13313         sync; sync_all_data
13314         cancel_lru_locks $OSC
13315         sleep 5
13316         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13317         want=$((OSTCOUNT * 1048576))
13318
13319         # Must allocate all requested space, not more than 5% extra
13320         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13321                 error "bytes $bytes is not $want"
13322 }
13323 run_test 150c "Verify fallocate Size and Blocks"
13324
13325 test_150d() {
13326         local bytes
13327         local want
13328
13329         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13330         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13331                 skip "Need OST version at least 2.13.53"
13332
13333         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13334         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13335         sync; sync_all_data
13336         cancel_lru_locks $OSC
13337         sleep 5
13338         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13339         want=$((OSTCOUNT * 1048576))
13340
13341         # Must allocate all requested space, not more than 5% extra
13342         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13343                 error "bytes $bytes is not $want"
13344 }
13345 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13346
13347 #LU-2902 roc_hit was not able to read all values from lproc
13348 function roc_hit_init() {
13349         local list=$(comma_list $(osts_nodes))
13350         local dir=$DIR/$tdir-check
13351         local file=$dir/$tfile
13352         local BEFORE
13353         local AFTER
13354         local idx
13355
13356         test_mkdir $dir
13357         #use setstripe to do a write to every ost
13358         for i in $(seq 0 $((OSTCOUNT-1))); do
13359                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13360                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13361                 idx=$(printf %04x $i)
13362                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13363                         awk '$1 == "cache_access" {sum += $7}
13364                                 END { printf("%0.0f", sum) }')
13365
13366                 cancel_lru_locks osc
13367                 cat $file >/dev/null
13368
13369                 AFTER=$(get_osd_param $list *OST*$idx stats |
13370                         awk '$1 == "cache_access" {sum += $7}
13371                                 END { printf("%0.0f", sum) }')
13372
13373                 echo BEFORE:$BEFORE AFTER:$AFTER
13374                 if ! let "AFTER - BEFORE == 4"; then
13375                         rm -rf $dir
13376                         error "roc_hit is not safe to use"
13377                 fi
13378                 rm $file
13379         done
13380
13381         rm -rf $dir
13382 }
13383
13384 function roc_hit() {
13385         local list=$(comma_list $(osts_nodes))
13386         echo $(get_osd_param $list '' stats |
13387                 awk '$1 == "cache_hit" {sum += $7}
13388                         END { printf("%0.0f", sum) }')
13389 }
13390
13391 function set_cache() {
13392         local on=1
13393
13394         if [ "$2" == "off" ]; then
13395                 on=0;
13396         fi
13397         local list=$(comma_list $(osts_nodes))
13398         set_osd_param $list '' $1_cache_enable $on
13399
13400         cancel_lru_locks osc
13401 }
13402
13403 test_151() {
13404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13405         remote_ost_nodsh && skip "remote OST with nodsh"
13406
13407         local CPAGES=3
13408         local list=$(comma_list $(osts_nodes))
13409
13410         # check whether obdfilter is cache capable at all
13411         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13412                 skip "not cache-capable obdfilter"
13413         fi
13414
13415         # check cache is enabled on all obdfilters
13416         if get_osd_param $list '' read_cache_enable | grep 0; then
13417                 skip "oss cache is disabled"
13418         fi
13419
13420         set_osd_param $list '' writethrough_cache_enable 1
13421
13422         # check write cache is enabled on all obdfilters
13423         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13424                 skip "oss write cache is NOT enabled"
13425         fi
13426
13427         roc_hit_init
13428
13429         #define OBD_FAIL_OBD_NO_LRU  0x609
13430         do_nodes $list $LCTL set_param fail_loc=0x609
13431
13432         # pages should be in the case right after write
13433         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13434                 error "dd failed"
13435
13436         local BEFORE=$(roc_hit)
13437         cancel_lru_locks osc
13438         cat $DIR/$tfile >/dev/null
13439         local AFTER=$(roc_hit)
13440
13441         do_nodes $list $LCTL set_param fail_loc=0
13442
13443         if ! let "AFTER - BEFORE == CPAGES"; then
13444                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13445         fi
13446
13447         cancel_lru_locks osc
13448         # invalidates OST cache
13449         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13450         set_osd_param $list '' read_cache_enable 0
13451         cat $DIR/$tfile >/dev/null
13452
13453         # now data shouldn't be found in the cache
13454         BEFORE=$(roc_hit)
13455         cancel_lru_locks osc
13456         cat $DIR/$tfile >/dev/null
13457         AFTER=$(roc_hit)
13458         if let "AFTER - BEFORE != 0"; then
13459                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13460         fi
13461
13462         set_osd_param $list '' read_cache_enable 1
13463         rm -f $DIR/$tfile
13464 }
13465 run_test 151 "test cache on oss and controls ==============================="
13466
13467 test_152() {
13468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13469
13470         local TF="$TMP/$tfile"
13471
13472         # simulate ENOMEM during write
13473 #define OBD_FAIL_OST_NOMEM      0x226
13474         lctl set_param fail_loc=0x80000226
13475         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13476         cp $TF $DIR/$tfile
13477         sync || error "sync failed"
13478         lctl set_param fail_loc=0
13479
13480         # discard client's cache
13481         cancel_lru_locks osc
13482
13483         # simulate ENOMEM during read
13484         lctl set_param fail_loc=0x80000226
13485         cmp $TF $DIR/$tfile || error "cmp failed"
13486         lctl set_param fail_loc=0
13487
13488         rm -f $TF
13489 }
13490 run_test 152 "test read/write with enomem ============================"
13491
13492 test_153() {
13493         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13494 }
13495 run_test 153 "test if fdatasync does not crash ======================="
13496
13497 dot_lustre_fid_permission_check() {
13498         local fid=$1
13499         local ffid=$MOUNT/.lustre/fid/$fid
13500         local test_dir=$2
13501
13502         echo "stat fid $fid"
13503         stat $ffid > /dev/null || error "stat $ffid failed."
13504         echo "touch fid $fid"
13505         touch $ffid || error "touch $ffid failed."
13506         echo "write to fid $fid"
13507         cat /etc/hosts > $ffid || error "write $ffid failed."
13508         echo "read fid $fid"
13509         diff /etc/hosts $ffid || error "read $ffid failed."
13510         echo "append write to fid $fid"
13511         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13512         echo "rename fid $fid"
13513         mv $ffid $test_dir/$tfile.1 &&
13514                 error "rename $ffid to $tfile.1 should fail."
13515         touch $test_dir/$tfile.1
13516         mv $test_dir/$tfile.1 $ffid &&
13517                 error "rename $tfile.1 to $ffid should fail."
13518         rm -f $test_dir/$tfile.1
13519         echo "truncate fid $fid"
13520         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13521         echo "link fid $fid"
13522         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13523         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13524                 echo "setfacl fid $fid"
13525                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13526                 echo "getfacl fid $fid"
13527                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13528         fi
13529         echo "unlink fid $fid"
13530         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13531         echo "mknod fid $fid"
13532         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13533
13534         fid=[0xf00000400:0x1:0x0]
13535         ffid=$MOUNT/.lustre/fid/$fid
13536
13537         echo "stat non-exist fid $fid"
13538         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13539         echo "write to non-exist fid $fid"
13540         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13541         echo "link new fid $fid"
13542         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13543
13544         mkdir -p $test_dir/$tdir
13545         touch $test_dir/$tdir/$tfile
13546         fid=$($LFS path2fid $test_dir/$tdir)
13547         rc=$?
13548         [ $rc -ne 0 ] &&
13549                 error "error: could not get fid for $test_dir/$dir/$tfile."
13550
13551         ffid=$MOUNT/.lustre/fid/$fid
13552
13553         echo "ls $fid"
13554         ls $ffid > /dev/null || error "ls $ffid failed."
13555         echo "touch $fid/$tfile.1"
13556         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13557
13558         echo "touch $MOUNT/.lustre/fid/$tfile"
13559         touch $MOUNT/.lustre/fid/$tfile && \
13560                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13561
13562         echo "setxattr to $MOUNT/.lustre/fid"
13563         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13564
13565         echo "listxattr for $MOUNT/.lustre/fid"
13566         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13567
13568         echo "delxattr from $MOUNT/.lustre/fid"
13569         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13570
13571         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13572         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13573                 error "touch invalid fid should fail."
13574
13575         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13576         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13577                 error "touch non-normal fid should fail."
13578
13579         echo "rename $tdir to $MOUNT/.lustre/fid"
13580         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13581                 error "rename to $MOUNT/.lustre/fid should fail."
13582
13583         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13584         then            # LU-3547
13585                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13586                 local new_obf_mode=777
13587
13588                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13589                 chmod $new_obf_mode $DIR/.lustre/fid ||
13590                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13591
13592                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13593                 [ $obf_mode -eq $new_obf_mode ] ||
13594                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13595
13596                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13597                 chmod $old_obf_mode $DIR/.lustre/fid ||
13598                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13599         fi
13600
13601         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13602         fid=$($LFS path2fid $test_dir/$tfile-2)
13603
13604         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13605         then # LU-5424
13606                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13607                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13608                         error "create lov data thru .lustre failed"
13609         fi
13610         echo "cp /etc/passwd $test_dir/$tfile-2"
13611         cp /etc/passwd $test_dir/$tfile-2 ||
13612                 error "copy to $test_dir/$tfile-2 failed."
13613         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13614         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13615                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13616
13617         rm -rf $test_dir/tfile.lnk
13618         rm -rf $test_dir/$tfile-2
13619 }
13620
13621 test_154A() {
13622         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13623                 skip "Need MDS version at least 2.4.1"
13624
13625         local tf=$DIR/$tfile
13626         touch $tf
13627
13628         local fid=$($LFS path2fid $tf)
13629         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13630
13631         # check that we get the same pathname back
13632         local rootpath
13633         local found
13634         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
13635                 echo "$rootpath $fid"
13636                 found=$($LFS fid2path $rootpath "$fid")
13637                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13638                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
13639         done
13640
13641         # check wrong root path format
13642         rootpath=$MOUNT"_wrong"
13643         found=$($LFS fid2path $rootpath "$fid")
13644         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
13645 }
13646 run_test 154A "lfs path2fid and fid2path basic checks"
13647
13648 test_154B() {
13649         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13650                 skip "Need MDS version at least 2.4.1"
13651
13652         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13653         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13654         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13655         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13656
13657         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13658         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13659
13660         # check that we get the same pathname
13661         echo "PFID: $PFID, name: $name"
13662         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13663         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13664         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13665                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13666
13667         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13668 }
13669 run_test 154B "verify the ll_decode_linkea tool"
13670
13671 test_154a() {
13672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13673         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13674         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13675                 skip "Need MDS version at least 2.2.51"
13676         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13677
13678         cp /etc/hosts $DIR/$tfile
13679
13680         fid=$($LFS path2fid $DIR/$tfile)
13681         rc=$?
13682         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13683
13684         dot_lustre_fid_permission_check "$fid" $DIR ||
13685                 error "dot lustre permission check $fid failed"
13686
13687         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13688
13689         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13690
13691         touch $MOUNT/.lustre/file &&
13692                 error "creation is not allowed under .lustre"
13693
13694         mkdir $MOUNT/.lustre/dir &&
13695                 error "mkdir is not allowed under .lustre"
13696
13697         rm -rf $DIR/$tfile
13698 }
13699 run_test 154a "Open-by-FID"
13700
13701 test_154b() {
13702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13703         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13704         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13705         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13706                 skip "Need MDS version at least 2.2.51"
13707
13708         local remote_dir=$DIR/$tdir/remote_dir
13709         local MDTIDX=1
13710         local rc=0
13711
13712         mkdir -p $DIR/$tdir
13713         $LFS mkdir -i $MDTIDX $remote_dir ||
13714                 error "create remote directory failed"
13715
13716         cp /etc/hosts $remote_dir/$tfile
13717
13718         fid=$($LFS path2fid $remote_dir/$tfile)
13719         rc=$?
13720         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13721
13722         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13723                 error "dot lustre permission check $fid failed"
13724         rm -rf $DIR/$tdir
13725 }
13726 run_test 154b "Open-by-FID for remote directory"
13727
13728 test_154c() {
13729         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13730                 skip "Need MDS version at least 2.4.1"
13731
13732         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13733         local FID1=$($LFS path2fid $DIR/$tfile.1)
13734         local FID2=$($LFS path2fid $DIR/$tfile.2)
13735         local FID3=$($LFS path2fid $DIR/$tfile.3)
13736
13737         local N=1
13738         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13739                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13740                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13741                 local want=FID$N
13742                 [ "$FID" = "${!want}" ] ||
13743                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13744                 N=$((N + 1))
13745         done
13746
13747         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13748         do
13749                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13750                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13751                 N=$((N + 1))
13752         done
13753 }
13754 run_test 154c "lfs path2fid and fid2path multiple arguments"
13755
13756 test_154d() {
13757         remote_mds_nodsh && skip "remote MDS with nodsh"
13758         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13759                 skip "Need MDS version at least 2.5.53"
13760
13761         if remote_mds; then
13762                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13763         else
13764                 nid="0@lo"
13765         fi
13766         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13767         local fd
13768         local cmd
13769
13770         rm -f $DIR/$tfile
13771         touch $DIR/$tfile
13772
13773         local fid=$($LFS path2fid $DIR/$tfile)
13774         # Open the file
13775         fd=$(free_fd)
13776         cmd="exec $fd<$DIR/$tfile"
13777         eval $cmd
13778         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13779         echo "$fid_list" | grep "$fid"
13780         rc=$?
13781
13782         cmd="exec $fd>/dev/null"
13783         eval $cmd
13784         if [ $rc -ne 0 ]; then
13785                 error "FID $fid not found in open files list $fid_list"
13786         fi
13787 }
13788 run_test 154d "Verify open file fid"
13789
13790 test_154e()
13791 {
13792         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13793                 skip "Need MDS version at least 2.6.50"
13794
13795         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13796                 error ".lustre returned by readdir"
13797         fi
13798 }
13799 run_test 154e ".lustre is not returned by readdir"
13800
13801 test_154f() {
13802         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13803
13804         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13805         test_mkdir -p -c1 $DIR/$tdir/d
13806         # test dirs inherit from its stripe
13807         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13808         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13809         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13810         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13811         touch $DIR/f
13812
13813         # get fid of parents
13814         local FID0=$($LFS path2fid $DIR/$tdir/d)
13815         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13816         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13817         local FID3=$($LFS path2fid $DIR)
13818
13819         # check that path2fid --parents returns expected <parent_fid>/name
13820         # 1) test for a directory (single parent)
13821         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13822         [ "$parent" == "$FID0/foo1" ] ||
13823                 error "expected parent: $FID0/foo1, got: $parent"
13824
13825         # 2) test for a file with nlink > 1 (multiple parents)
13826         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13827         echo "$parent" | grep -F "$FID1/$tfile" ||
13828                 error "$FID1/$tfile not returned in parent list"
13829         echo "$parent" | grep -F "$FID2/link" ||
13830                 error "$FID2/link not returned in parent list"
13831
13832         # 3) get parent by fid
13833         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13834         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13835         echo "$parent" | grep -F "$FID1/$tfile" ||
13836                 error "$FID1/$tfile not returned in parent list (by fid)"
13837         echo "$parent" | grep -F "$FID2/link" ||
13838                 error "$FID2/link not returned in parent list (by fid)"
13839
13840         # 4) test for entry in root directory
13841         parent=$($LFS path2fid --parents $DIR/f)
13842         echo "$parent" | grep -F "$FID3/f" ||
13843                 error "$FID3/f not returned in parent list"
13844
13845         # 5) test it on root directory
13846         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13847                 error "$MOUNT should not have parents"
13848
13849         # enable xattr caching and check that linkea is correctly updated
13850         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13851         save_lustre_params client "llite.*.xattr_cache" > $save
13852         lctl set_param llite.*.xattr_cache 1
13853
13854         # 6.1) linkea update on rename
13855         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13856
13857         # get parents by fid
13858         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13859         # foo1 should no longer be returned in parent list
13860         echo "$parent" | grep -F "$FID1" &&
13861                 error "$FID1 should no longer be in parent list"
13862         # the new path should appear
13863         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13864                 error "$FID2/$tfile.moved is not in parent list"
13865
13866         # 6.2) linkea update on unlink
13867         rm -f $DIR/$tdir/d/foo2/link
13868         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13869         # foo2/link should no longer be returned in parent list
13870         echo "$parent" | grep -F "$FID2/link" &&
13871                 error "$FID2/link should no longer be in parent list"
13872         true
13873
13874         rm -f $DIR/f
13875         restore_lustre_params < $save
13876         rm -f $save
13877 }
13878 run_test 154f "get parent fids by reading link ea"
13879
13880 test_154g()
13881 {
13882         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13883         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
13884            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
13885                 skip "Need MDS version at least 2.6.92"
13886
13887         mkdir -p $DIR/$tdir
13888         llapi_fid_test -d $DIR/$tdir
13889 }
13890 run_test 154g "various llapi FID tests"
13891
13892 test_155_small_load() {
13893     local temp=$TMP/$tfile
13894     local file=$DIR/$tfile
13895
13896     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
13897         error "dd of=$temp bs=6096 count=1 failed"
13898     cp $temp $file
13899     cancel_lru_locks $OSC
13900     cmp $temp $file || error "$temp $file differ"
13901
13902     $TRUNCATE $temp 6000
13903     $TRUNCATE $file 6000
13904     cmp $temp $file || error "$temp $file differ (truncate1)"
13905
13906     echo "12345" >>$temp
13907     echo "12345" >>$file
13908     cmp $temp $file || error "$temp $file differ (append1)"
13909
13910     echo "12345" >>$temp
13911     echo "12345" >>$file
13912     cmp $temp $file || error "$temp $file differ (append2)"
13913
13914     rm -f $temp $file
13915     true
13916 }
13917
13918 test_155_big_load() {
13919         remote_ost_nodsh && skip "remote OST with nodsh"
13920
13921         local temp=$TMP/$tfile
13922         local file=$DIR/$tfile
13923
13924         free_min_max
13925         local cache_size=$(do_facet ost$((MAXI+1)) \
13926                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
13927         local large_file_size=$((cache_size * 2))
13928
13929         echo "OSS cache size: $cache_size KB"
13930         echo "Large file size: $large_file_size KB"
13931
13932         [ $MAXV -le $large_file_size ] &&
13933                 skip_env "max available OST size needs > $large_file_size KB"
13934
13935         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
13936
13937         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
13938                 error "dd of=$temp bs=$large_file_size count=1k failed"
13939         cp $temp $file
13940         ls -lh $temp $file
13941         cancel_lru_locks osc
13942         cmp $temp $file || error "$temp $file differ"
13943
13944         rm -f $temp $file
13945         true
13946 }
13947
13948 save_writethrough() {
13949         local facets=$(get_facets OST)
13950
13951         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
13952 }
13953
13954 test_155a() {
13955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13956
13957         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13958
13959         save_writethrough $p
13960
13961         set_cache read on
13962         set_cache writethrough on
13963         test_155_small_load
13964         restore_lustre_params < $p
13965         rm -f $p
13966 }
13967 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
13968
13969 test_155b() {
13970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13971
13972         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13973
13974         save_writethrough $p
13975
13976         set_cache read on
13977         set_cache writethrough off
13978         test_155_small_load
13979         restore_lustre_params < $p
13980         rm -f $p
13981 }
13982 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
13983
13984 test_155c() {
13985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13986
13987         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13988
13989         save_writethrough $p
13990
13991         set_cache read off
13992         set_cache writethrough on
13993         test_155_small_load
13994         restore_lustre_params < $p
13995         rm -f $p
13996 }
13997 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
13998
13999 test_155d() {
14000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14001
14002         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14003
14004         save_writethrough $p
14005
14006         set_cache read off
14007         set_cache writethrough off
14008         test_155_small_load
14009         restore_lustre_params < $p
14010         rm -f $p
14011 }
14012 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14013
14014 test_155e() {
14015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14016
14017         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14018
14019         save_writethrough $p
14020
14021         set_cache read on
14022         set_cache writethrough on
14023         test_155_big_load
14024         restore_lustre_params < $p
14025         rm -f $p
14026 }
14027 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14028
14029 test_155f() {
14030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14031
14032         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14033
14034         save_writethrough $p
14035
14036         set_cache read on
14037         set_cache writethrough off
14038         test_155_big_load
14039         restore_lustre_params < $p
14040         rm -f $p
14041 }
14042 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14043
14044 test_155g() {
14045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14046
14047         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14048
14049         save_writethrough $p
14050
14051         set_cache read off
14052         set_cache writethrough on
14053         test_155_big_load
14054         restore_lustre_params < $p
14055         rm -f $p
14056 }
14057 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14058
14059 test_155h() {
14060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14061
14062         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14063
14064         save_writethrough $p
14065
14066         set_cache read off
14067         set_cache writethrough off
14068         test_155_big_load
14069         restore_lustre_params < $p
14070         rm -f $p
14071 }
14072 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14073
14074 test_156() {
14075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14076         remote_ost_nodsh && skip "remote OST with nodsh"
14077         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14078                 skip "stats not implemented on old servers"
14079         [ "$ost1_FSTYPE" = "zfs" ] &&
14080                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14081
14082         local CPAGES=3
14083         local BEFORE
14084         local AFTER
14085         local file="$DIR/$tfile"
14086         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14087
14088         save_writethrough $p
14089         roc_hit_init
14090
14091         log "Turn on read and write cache"
14092         set_cache read on
14093         set_cache writethrough on
14094
14095         log "Write data and read it back."
14096         log "Read should be satisfied from the cache."
14097         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14098         BEFORE=$(roc_hit)
14099         cancel_lru_locks osc
14100         cat $file >/dev/null
14101         AFTER=$(roc_hit)
14102         if ! let "AFTER - BEFORE == CPAGES"; then
14103                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14104         else
14105                 log "cache hits: before: $BEFORE, after: $AFTER"
14106         fi
14107
14108         log "Read again; it should be satisfied from the cache."
14109         BEFORE=$AFTER
14110         cancel_lru_locks osc
14111         cat $file >/dev/null
14112         AFTER=$(roc_hit)
14113         if ! let "AFTER - BEFORE == CPAGES"; then
14114                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14115         else
14116                 log "cache hits:: before: $BEFORE, after: $AFTER"
14117         fi
14118
14119         log "Turn off the read cache and turn on the write cache"
14120         set_cache read off
14121         set_cache writethrough on
14122
14123         log "Read again; it should be satisfied from the cache."
14124         BEFORE=$(roc_hit)
14125         cancel_lru_locks osc
14126         cat $file >/dev/null
14127         AFTER=$(roc_hit)
14128         if ! let "AFTER - BEFORE == CPAGES"; then
14129                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14130         else
14131                 log "cache hits:: before: $BEFORE, after: $AFTER"
14132         fi
14133
14134         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14135                 # > 2.12.56 uses pagecache if cached
14136                 log "Read again; it should not be satisfied from the cache."
14137                 BEFORE=$AFTER
14138                 cancel_lru_locks osc
14139                 cat $file >/dev/null
14140                 AFTER=$(roc_hit)
14141                 if ! let "AFTER - BEFORE == 0"; then
14142                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14143                 else
14144                         log "cache hits:: before: $BEFORE, after: $AFTER"
14145                 fi
14146         fi
14147
14148         log "Write data and read it back."
14149         log "Read should be satisfied from the cache."
14150         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14151         BEFORE=$(roc_hit)
14152         cancel_lru_locks osc
14153         cat $file >/dev/null
14154         AFTER=$(roc_hit)
14155         if ! let "AFTER - BEFORE == CPAGES"; then
14156                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14157         else
14158                 log "cache hits:: before: $BEFORE, after: $AFTER"
14159         fi
14160
14161         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14162                 # > 2.12.56 uses pagecache if cached
14163                 log "Read again; it should not be satisfied from the cache."
14164                 BEFORE=$AFTER
14165                 cancel_lru_locks osc
14166                 cat $file >/dev/null
14167                 AFTER=$(roc_hit)
14168                 if ! let "AFTER - BEFORE == 0"; then
14169                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14170                 else
14171                         log "cache hits:: before: $BEFORE, after: $AFTER"
14172                 fi
14173         fi
14174
14175         log "Turn off read and write cache"
14176         set_cache read off
14177         set_cache writethrough off
14178
14179         log "Write data and read it back"
14180         log "It should not be satisfied from the cache."
14181         rm -f $file
14182         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14183         cancel_lru_locks osc
14184         BEFORE=$(roc_hit)
14185         cat $file >/dev/null
14186         AFTER=$(roc_hit)
14187         if ! let "AFTER - BEFORE == 0"; then
14188                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14189         else
14190                 log "cache hits:: before: $BEFORE, after: $AFTER"
14191         fi
14192
14193         log "Turn on the read cache and turn off the write cache"
14194         set_cache read on
14195         set_cache writethrough off
14196
14197         log "Write data and read it back"
14198         log "It should not be satisfied from the cache."
14199         rm -f $file
14200         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14201         BEFORE=$(roc_hit)
14202         cancel_lru_locks osc
14203         cat $file >/dev/null
14204         AFTER=$(roc_hit)
14205         if ! let "AFTER - BEFORE == 0"; then
14206                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14207         else
14208                 log "cache hits:: before: $BEFORE, after: $AFTER"
14209         fi
14210
14211         log "Read again; it should be satisfied from the cache."
14212         BEFORE=$(roc_hit)
14213         cancel_lru_locks osc
14214         cat $file >/dev/null
14215         AFTER=$(roc_hit)
14216         if ! let "AFTER - BEFORE == CPAGES"; then
14217                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14218         else
14219                 log "cache hits:: before: $BEFORE, after: $AFTER"
14220         fi
14221
14222         restore_lustre_params < $p
14223         rm -f $p $file
14224 }
14225 run_test 156 "Verification of tunables"
14226
14227 test_160a() {
14228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14229         remote_mds_nodsh && skip "remote MDS with nodsh"
14230         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14231                 skip "Need MDS version at least 2.2.0"
14232
14233         changelog_register || error "changelog_register failed"
14234         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14235         changelog_users $SINGLEMDS | grep -q $cl_user ||
14236                 error "User $cl_user not found in changelog_users"
14237
14238         # change something
14239         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14240         changelog_clear 0 || error "changelog_clear failed"
14241         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14242         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14243         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14244         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14245         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14246         rm $DIR/$tdir/pics/desktop.jpg
14247
14248         changelog_dump | tail -10
14249
14250         echo "verifying changelog mask"
14251         changelog_chmask "-MKDIR"
14252         changelog_chmask "-CLOSE"
14253
14254         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14255         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14256
14257         changelog_chmask "+MKDIR"
14258         changelog_chmask "+CLOSE"
14259
14260         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14261         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14262
14263         changelog_dump | tail -10
14264         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14265         CLOSES=$(changelog_dump | grep -c "CLOSE")
14266         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14267         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14268
14269         # verify contents
14270         echo "verifying target fid"
14271         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14272         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14273         [ "$fidc" == "$fidf" ] ||
14274                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14275         echo "verifying parent fid"
14276         # The FID returned from the Changelog may be the directory shard on
14277         # a different MDT, and not the FID returned by path2fid on the parent.
14278         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14279         # since this is what will matter when recreating this file in the tree.
14280         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14281         local pathp=$($LFS fid2path $MOUNT "$fidp")
14282         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14283                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14284
14285         echo "getting records for $cl_user"
14286         changelog_users $SINGLEMDS
14287         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14288         local nclr=3
14289         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14290                 error "changelog_clear failed"
14291         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14292         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14293         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14294                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14295
14296         local min0_rec=$(changelog_users $SINGLEMDS |
14297                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14298         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14299                           awk '{ print $1; exit; }')
14300
14301         changelog_dump | tail -n 5
14302         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14303         [ $first_rec == $((min0_rec + 1)) ] ||
14304                 error "first index should be $min0_rec + 1 not $first_rec"
14305
14306         # LU-3446 changelog index reset on MDT restart
14307         local cur_rec1=$(changelog_users $SINGLEMDS |
14308                          awk '/^current.index:/ { print $NF }')
14309         changelog_clear 0 ||
14310                 error "clear all changelog records for $cl_user failed"
14311         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14312         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14313                 error "Fail to start $SINGLEMDS"
14314         local cur_rec2=$(changelog_users $SINGLEMDS |
14315                          awk '/^current.index:/ { print $NF }')
14316         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14317         [ $cur_rec1 == $cur_rec2 ] ||
14318                 error "current index should be $cur_rec1 not $cur_rec2"
14319
14320         echo "verifying users from this test are deregistered"
14321         changelog_deregister || error "changelog_deregister failed"
14322         changelog_users $SINGLEMDS | grep -q $cl_user &&
14323                 error "User '$cl_user' still in changelog_users"
14324
14325         # lctl get_param -n mdd.*.changelog_users
14326         # current index: 144
14327         # ID    index (idle seconds)
14328         # cl3   144 (2)
14329         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14330                 # this is the normal case where all users were deregistered
14331                 # make sure no new records are added when no users are present
14332                 local last_rec1=$(changelog_users $SINGLEMDS |
14333                                   awk '/^current.index:/ { print $NF }')
14334                 touch $DIR/$tdir/chloe
14335                 local last_rec2=$(changelog_users $SINGLEMDS |
14336                                   awk '/^current.index:/ { print $NF }')
14337                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14338                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14339         else
14340                 # any changelog users must be leftovers from a previous test
14341                 changelog_users $SINGLEMDS
14342                 echo "other changelog users; can't verify off"
14343         fi
14344 }
14345 run_test 160a "changelog sanity"
14346
14347 test_160b() { # LU-3587
14348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14349         remote_mds_nodsh && skip "remote MDS with nodsh"
14350         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14351                 skip "Need MDS version at least 2.2.0"
14352
14353         changelog_register || error "changelog_register failed"
14354         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14355         changelog_users $SINGLEMDS | grep -q $cl_user ||
14356                 error "User '$cl_user' not found in changelog_users"
14357
14358         local longname1=$(str_repeat a 255)
14359         local longname2=$(str_repeat b 255)
14360
14361         cd $DIR
14362         echo "creating very long named file"
14363         touch $longname1 || error "create of '$longname1' failed"
14364         echo "renaming very long named file"
14365         mv $longname1 $longname2
14366
14367         changelog_dump | grep RENME | tail -n 5
14368         rm -f $longname2
14369 }
14370 run_test 160b "Verify that very long rename doesn't crash in changelog"
14371
14372 test_160c() {
14373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14374         remote_mds_nodsh && skip "remote MDS with nodsh"
14375
14376         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14377                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14378                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14379                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14380
14381         local rc=0
14382
14383         # Registration step
14384         changelog_register || error "changelog_register failed"
14385
14386         rm -rf $DIR/$tdir
14387         mkdir -p $DIR/$tdir
14388         $MCREATE $DIR/$tdir/foo_160c
14389         changelog_chmask "-TRUNC"
14390         $TRUNCATE $DIR/$tdir/foo_160c 200
14391         changelog_chmask "+TRUNC"
14392         $TRUNCATE $DIR/$tdir/foo_160c 199
14393         changelog_dump | tail -n 5
14394         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14395         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14396 }
14397 run_test 160c "verify that changelog log catch the truncate event"
14398
14399 test_160d() {
14400         remote_mds_nodsh && skip "remote MDS with nodsh"
14401         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14403         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14404                 skip "Need MDS version at least 2.7.60"
14405
14406         # Registration step
14407         changelog_register || error "changelog_register failed"
14408
14409         mkdir -p $DIR/$tdir/migrate_dir
14410         changelog_clear 0 || error "changelog_clear failed"
14411
14412         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14413         changelog_dump | tail -n 5
14414         local migrates=$(changelog_dump | grep -c "MIGRT")
14415         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14416 }
14417 run_test 160d "verify that changelog log catch the migrate event"
14418
14419 test_160e() {
14420         remote_mds_nodsh && skip "remote MDS with nodsh"
14421
14422         # Create a user
14423         changelog_register || error "changelog_register failed"
14424
14425         # Delete a future user (expect fail)
14426         local MDT0=$(facet_svc $SINGLEMDS)
14427         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14428         local rc=$?
14429
14430         if [ $rc -eq 0 ]; then
14431                 error "Deleted non-existant user cl77"
14432         elif [ $rc -ne 2 ]; then
14433                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14434         fi
14435
14436         # Clear to a bad index (1 billion should be safe)
14437         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14438         rc=$?
14439
14440         if [ $rc -eq 0 ]; then
14441                 error "Successfully cleared to invalid CL index"
14442         elif [ $rc -ne 22 ]; then
14443                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14444         fi
14445 }
14446 run_test 160e "changelog negative testing (should return errors)"
14447
14448 test_160f() {
14449         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14450         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14451                 skip "Need MDS version at least 2.10.56"
14452
14453         local mdts=$(comma_list $(mdts_nodes))
14454
14455         # Create a user
14456         changelog_register || error "first changelog_register failed"
14457         changelog_register || error "second changelog_register failed"
14458         local cl_users
14459         declare -A cl_user1
14460         declare -A cl_user2
14461         local user_rec1
14462         local user_rec2
14463         local i
14464
14465         # generate some changelog records to accumulate on each MDT
14466         # use fnv1a because created files should be evenly distributed
14467         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14468                 error "test_mkdir $tdir failed"
14469         log "$(date +%s): creating first files"
14470         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14471                 error "create $DIR/$tdir/$tfile failed"
14472
14473         # check changelogs have been generated
14474         local start=$SECONDS
14475         local idle_time=$((MDSCOUNT * 5 + 5))
14476         local nbcl=$(changelog_dump | wc -l)
14477         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14478
14479         for param in "changelog_max_idle_time=$idle_time" \
14480                      "changelog_gc=1" \
14481                      "changelog_min_gc_interval=2" \
14482                      "changelog_min_free_cat_entries=3"; do
14483                 local MDT0=$(facet_svc $SINGLEMDS)
14484                 local var="${param%=*}"
14485                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14486
14487                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14488                 do_nodes $mdts $LCTL set_param mdd.*.$param
14489         done
14490
14491         # force cl_user2 to be idle (1st part), but also cancel the
14492         # cl_user1 records so that it is not evicted later in the test.
14493         local sleep1=$((idle_time / 2))
14494         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14495         sleep $sleep1
14496
14497         # simulate changelog catalog almost full
14498         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14499         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14500
14501         for i in $(seq $MDSCOUNT); do
14502                 cl_users=(${CL_USERS[mds$i]})
14503                 cl_user1[mds$i]="${cl_users[0]}"
14504                 cl_user2[mds$i]="${cl_users[1]}"
14505
14506                 [ -n "${cl_user1[mds$i]}" ] ||
14507                         error "mds$i: no user registered"
14508                 [ -n "${cl_user2[mds$i]}" ] ||
14509                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14510
14511                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14512                 [ -n "$user_rec1" ] ||
14513                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14514                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14515                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14516                 [ -n "$user_rec2" ] ||
14517                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14518                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14519                      "$user_rec1 + 2 == $user_rec2"
14520                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14521                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14522                               "$user_rec1 + 2, but is $user_rec2"
14523                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14524                 [ -n "$user_rec2" ] ||
14525                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14526                 [ $user_rec1 == $user_rec2 ] ||
14527                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14528                               "$user_rec1, but is $user_rec2"
14529         done
14530
14531         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14532         local sleep2=$((idle_time - (SECONDS - start) + 1))
14533         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14534         sleep $sleep2
14535
14536         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14537         # cl_user1 should be OK because it recently processed records.
14538         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14539         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14540                 error "create $DIR/$tdir/${tfile}b failed"
14541
14542         # ensure gc thread is done
14543         for i in $(mdts_nodes); do
14544                 wait_update $i \
14545                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14546                         error "$i: GC-thread not done"
14547         done
14548
14549         local first_rec
14550         for i in $(seq $MDSCOUNT); do
14551                 # check cl_user1 still registered
14552                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14553                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14554                 # check cl_user2 unregistered
14555                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14556                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14557
14558                 # check changelogs are present and starting at $user_rec1 + 1
14559                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14560                 [ -n "$user_rec1" ] ||
14561                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14562                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14563                             awk '{ print $1; exit; }')
14564
14565                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14566                 [ $((user_rec1 + 1)) == $first_rec ] ||
14567                         error "mds$i: first index should be $user_rec1 + 1, " \
14568                               "but is $first_rec"
14569         done
14570 }
14571 run_test 160f "changelog garbage collect (timestamped users)"
14572
14573 test_160g() {
14574         remote_mds_nodsh && skip "remote MDS with nodsh"
14575         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14576                 skip "Need MDS version at least 2.10.56"
14577
14578         local mdts=$(comma_list $(mdts_nodes))
14579
14580         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14581         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14582
14583         # Create a user
14584         changelog_register || error "first changelog_register failed"
14585         changelog_register || error "second changelog_register failed"
14586         local cl_users
14587         declare -A cl_user1
14588         declare -A cl_user2
14589         local user_rec1
14590         local user_rec2
14591         local i
14592
14593         # generate some changelog records to accumulate on each MDT
14594         # use fnv1a because created files should be evenly distributed
14595         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14596                 error "mkdir $tdir failed"
14597         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14598                 error "create $DIR/$tdir/$tfile failed"
14599
14600         # check changelogs have been generated
14601         local nbcl=$(changelog_dump | wc -l)
14602         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14603
14604         # reduce the max_idle_indexes value to make sure we exceed it
14605         max_ndx=$((nbcl / 2 - 1))
14606
14607         for param in "changelog_max_idle_indexes=$max_ndx" \
14608                      "changelog_gc=1" \
14609                      "changelog_min_gc_interval=2" \
14610                      "changelog_min_free_cat_entries=3"; do
14611                 local MDT0=$(facet_svc $SINGLEMDS)
14612                 local var="${param%=*}"
14613                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14614
14615                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14616                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14617                         error "unable to set mdd.*.$param"
14618         done
14619
14620         # simulate changelog catalog almost full
14621         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14622         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14623
14624         for i in $(seq $MDSCOUNT); do
14625                 cl_users=(${CL_USERS[mds$i]})
14626                 cl_user1[mds$i]="${cl_users[0]}"
14627                 cl_user2[mds$i]="${cl_users[1]}"
14628
14629                 [ -n "${cl_user1[mds$i]}" ] ||
14630                         error "mds$i: no user registered"
14631                 [ -n "${cl_user2[mds$i]}" ] ||
14632                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14633
14634                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14635                 [ -n "$user_rec1" ] ||
14636                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14637                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14638                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14639                 [ -n "$user_rec2" ] ||
14640                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14641                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14642                      "$user_rec1 + 2 == $user_rec2"
14643                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14644                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14645                               "$user_rec1 + 2, but is $user_rec2"
14646                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14647                 [ -n "$user_rec2" ] ||
14648                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14649                 [ $user_rec1 == $user_rec2 ] ||
14650                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14651                               "$user_rec1, but is $user_rec2"
14652         done
14653
14654         # ensure we are past the previous changelog_min_gc_interval set above
14655         sleep 2
14656
14657         # generate one more changelog to trigger fail_loc
14658         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14659                 error "create $DIR/$tdir/${tfile}bis failed"
14660
14661         # ensure gc thread is done
14662         for i in $(mdts_nodes); do
14663                 wait_update $i \
14664                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14665                         error "$i: GC-thread not done"
14666         done
14667
14668         local first_rec
14669         for i in $(seq $MDSCOUNT); do
14670                 # check cl_user1 still registered
14671                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14672                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14673                 # check cl_user2 unregistered
14674                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14675                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14676
14677                 # check changelogs are present and starting at $user_rec1 + 1
14678                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14679                 [ -n "$user_rec1" ] ||
14680                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14681                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14682                             awk '{ print $1; exit; }')
14683
14684                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14685                 [ $((user_rec1 + 1)) == $first_rec ] ||
14686                         error "mds$i: first index should be $user_rec1 + 1, " \
14687                               "but is $first_rec"
14688         done
14689 }
14690 run_test 160g "changelog garbage collect (old users)"
14691
14692 test_160h() {
14693         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14694         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14695                 skip "Need MDS version at least 2.10.56"
14696
14697         local mdts=$(comma_list $(mdts_nodes))
14698
14699         # Create a user
14700         changelog_register || error "first changelog_register failed"
14701         changelog_register || error "second changelog_register failed"
14702         local cl_users
14703         declare -A cl_user1
14704         declare -A cl_user2
14705         local user_rec1
14706         local user_rec2
14707         local i
14708
14709         # generate some changelog records to accumulate on each MDT
14710         # use fnv1a because created files should be evenly distributed
14711         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14712                 error "test_mkdir $tdir failed"
14713         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14714                 error "create $DIR/$tdir/$tfile failed"
14715
14716         # check changelogs have been generated
14717         local nbcl=$(changelog_dump | wc -l)
14718         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14719
14720         for param in "changelog_max_idle_time=10" \
14721                      "changelog_gc=1" \
14722                      "changelog_min_gc_interval=2"; do
14723                 local MDT0=$(facet_svc $SINGLEMDS)
14724                 local var="${param%=*}"
14725                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14726
14727                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14728                 do_nodes $mdts $LCTL set_param mdd.*.$param
14729         done
14730
14731         # force cl_user2 to be idle (1st part)
14732         sleep 9
14733
14734         for i in $(seq $MDSCOUNT); do
14735                 cl_users=(${CL_USERS[mds$i]})
14736                 cl_user1[mds$i]="${cl_users[0]}"
14737                 cl_user2[mds$i]="${cl_users[1]}"
14738
14739                 [ -n "${cl_user1[mds$i]}" ] ||
14740                         error "mds$i: no user registered"
14741                 [ -n "${cl_user2[mds$i]}" ] ||
14742                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14743
14744                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14745                 [ -n "$user_rec1" ] ||
14746                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14747                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14748                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14749                 [ -n "$user_rec2" ] ||
14750                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14751                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14752                      "$user_rec1 + 2 == $user_rec2"
14753                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14754                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14755                               "$user_rec1 + 2, but is $user_rec2"
14756                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14757                 [ -n "$user_rec2" ] ||
14758                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14759                 [ $user_rec1 == $user_rec2 ] ||
14760                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14761                               "$user_rec1, but is $user_rec2"
14762         done
14763
14764         # force cl_user2 to be idle (2nd part) and to reach
14765         # changelog_max_idle_time
14766         sleep 2
14767
14768         # force each GC-thread start and block then
14769         # one per MDT/MDD, set fail_val accordingly
14770         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14771         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14772
14773         # generate more changelogs to trigger fail_loc
14774         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14775                 error "create $DIR/$tdir/${tfile}bis failed"
14776
14777         # stop MDT to stop GC-thread, should be done in back-ground as it will
14778         # block waiting for the thread to be released and exit
14779         declare -A stop_pids
14780         for i in $(seq $MDSCOUNT); do
14781                 stop mds$i &
14782                 stop_pids[mds$i]=$!
14783         done
14784
14785         for i in $(mdts_nodes); do
14786                 local facet
14787                 local nb=0
14788                 local facets=$(facets_up_on_host $i)
14789
14790                 for facet in ${facets//,/ }; do
14791                         if [[ $facet == mds* ]]; then
14792                                 nb=$((nb + 1))
14793                         fi
14794                 done
14795                 # ensure each MDS's gc threads are still present and all in "R"
14796                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14797                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14798                         error "$i: expected $nb GC-thread"
14799                 wait_update $i \
14800                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14801                         "R" 20 ||
14802                         error "$i: GC-thread not found in R-state"
14803                 # check umounts of each MDT on MDS have reached kthread_stop()
14804                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14805                         error "$i: expected $nb umount"
14806                 wait_update $i \
14807                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14808                         error "$i: umount not found in D-state"
14809         done
14810
14811         # release all GC-threads
14812         do_nodes $mdts $LCTL set_param fail_loc=0
14813
14814         # wait for MDT stop to complete
14815         for i in $(seq $MDSCOUNT); do
14816                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14817         done
14818
14819         # XXX
14820         # may try to check if any orphan changelog records are present
14821         # via ldiskfs/zfs and llog_reader...
14822
14823         # re-start/mount MDTs
14824         for i in $(seq $MDSCOUNT); do
14825                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14826                         error "Fail to start mds$i"
14827         done
14828
14829         local first_rec
14830         for i in $(seq $MDSCOUNT); do
14831                 # check cl_user1 still registered
14832                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14833                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14834                 # check cl_user2 unregistered
14835                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14836                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14837
14838                 # check changelogs are present and starting at $user_rec1 + 1
14839                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14840                 [ -n "$user_rec1" ] ||
14841                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14842                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14843                             awk '{ print $1; exit; }')
14844
14845                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14846                 [ $((user_rec1 + 1)) == $first_rec ] ||
14847                         error "mds$i: first index should be $user_rec1 + 1, " \
14848                               "but is $first_rec"
14849         done
14850 }
14851 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14852               "during mount"
14853
14854 test_160i() {
14855
14856         local mdts=$(comma_list $(mdts_nodes))
14857
14858         changelog_register || error "first changelog_register failed"
14859
14860         # generate some changelog records to accumulate on each MDT
14861         # use fnv1a because created files should be evenly distributed
14862         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14863                 error "mkdir $tdir failed"
14864         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14865                 error "create $DIR/$tdir/$tfile failed"
14866
14867         # check changelogs have been generated
14868         local nbcl=$(changelog_dump | wc -l)
14869         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14870
14871         # simulate race between register and unregister
14872         # XXX as fail_loc is set per-MDS, with DNE configs the race
14873         # simulation will only occur for one MDT per MDS and for the
14874         # others the normal race scenario will take place
14875         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
14876         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
14877         do_nodes $mdts $LCTL set_param fail_val=1
14878
14879         # unregister 1st user
14880         changelog_deregister &
14881         local pid1=$!
14882         # wait some time for deregister work to reach race rdv
14883         sleep 2
14884         # register 2nd user
14885         changelog_register || error "2nd user register failed"
14886
14887         wait $pid1 || error "1st user deregister failed"
14888
14889         local i
14890         local last_rec
14891         declare -A LAST_REC
14892         for i in $(seq $MDSCOUNT); do
14893                 if changelog_users mds$i | grep "^cl"; then
14894                         # make sure new records are added with one user present
14895                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
14896                                           awk '/^current.index:/ { print $NF }')
14897                 else
14898                         error "mds$i has no user registered"
14899                 fi
14900         done
14901
14902         # generate more changelog records to accumulate on each MDT
14903         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14904                 error "create $DIR/$tdir/${tfile}bis failed"
14905
14906         for i in $(seq $MDSCOUNT); do
14907                 last_rec=$(changelog_users $SINGLEMDS |
14908                            awk '/^current.index:/ { print $NF }')
14909                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
14910                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
14911                         error "changelogs are off on mds$i"
14912         done
14913 }
14914 run_test 160i "changelog user register/unregister race"
14915
14916 test_160j() {
14917         remote_mds_nodsh && skip "remote MDS with nodsh"
14918         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
14919                 skip "Need MDS version at least 2.12.56"
14920
14921         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
14922         stack_trap "umount $MOUNT2" EXIT
14923
14924         changelog_register || error "first changelog_register failed"
14925         stack_trap "changelog_deregister" EXIT
14926
14927         # generate some changelog
14928         # use fnv1a because created files should be evenly distributed
14929         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14930                 error "mkdir $tdir failed"
14931         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14932                 error "create $DIR/$tdir/${tfile}bis failed"
14933
14934         # open the changelog device
14935         exec 3>/dev/changelog-$FSNAME-MDT0000
14936         stack_trap "exec 3>&-" EXIT
14937         exec 4</dev/changelog-$FSNAME-MDT0000
14938         stack_trap "exec 4<&-" EXIT
14939
14940         # umount the first lustre mount
14941         umount $MOUNT
14942         stack_trap "mount_client $MOUNT" EXIT
14943
14944         # read changelog
14945         cat <&4 >/dev/null || error "read changelog failed"
14946
14947         # clear changelog
14948         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14949         changelog_users $SINGLEMDS | grep -q $cl_user ||
14950                 error "User $cl_user not found in changelog_users"
14951
14952         printf 'clear:'$cl_user':0' >&3
14953 }
14954 run_test 160j "client can be umounted  while its chanangelog is being used"
14955
14956 test_160k() {
14957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14958         remote_mds_nodsh && skip "remote MDS with nodsh"
14959
14960         mkdir -p $DIR/$tdir/1/1
14961
14962         changelog_register || error "changelog_register failed"
14963         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14964
14965         changelog_users $SINGLEMDS | grep -q $cl_user ||
14966                 error "User '$cl_user' not found in changelog_users"
14967 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
14968         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
14969         rmdir $DIR/$tdir/1/1 & sleep 1
14970         mkdir $DIR/$tdir/2
14971         touch $DIR/$tdir/2/2
14972         rm -rf $DIR/$tdir/2
14973
14974         wait
14975         sleep 4
14976
14977         changelog_dump | grep rmdir || error "rmdir not recorded"
14978
14979         rm -rf $DIR/$tdir
14980         changelog_deregister
14981 }
14982 run_test 160k "Verify that changelog records are not lost"
14983
14984 test_161a() {
14985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14986
14987         test_mkdir -c1 $DIR/$tdir
14988         cp /etc/hosts $DIR/$tdir/$tfile
14989         test_mkdir -c1 $DIR/$tdir/foo1
14990         test_mkdir -c1 $DIR/$tdir/foo2
14991         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
14992         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
14993         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
14994         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
14995         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
14996         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
14997                 $LFS fid2path $DIR $FID
14998                 error "bad link ea"
14999         fi
15000         # middle
15001         rm $DIR/$tdir/foo2/zachary
15002         # last
15003         rm $DIR/$tdir/foo2/thor
15004         # first
15005         rm $DIR/$tdir/$tfile
15006         # rename
15007         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15008         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15009                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15010         rm $DIR/$tdir/foo2/maggie
15011
15012         # overflow the EA
15013         local longname=$tfile.avg_len_is_thirty_two_
15014         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15015                 error_noexit 'failed to unlink many hardlinks'" EXIT
15016         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15017                 error "failed to hardlink many files"
15018         links=$($LFS fid2path $DIR $FID | wc -l)
15019         echo -n "${links}/1000 links in link EA"
15020         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15021 }
15022 run_test 161a "link ea sanity"
15023
15024 test_161b() {
15025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15026         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15027
15028         local MDTIDX=1
15029         local remote_dir=$DIR/$tdir/remote_dir
15030
15031         mkdir -p $DIR/$tdir
15032         $LFS mkdir -i $MDTIDX $remote_dir ||
15033                 error "create remote directory failed"
15034
15035         cp /etc/hosts $remote_dir/$tfile
15036         mkdir -p $remote_dir/foo1
15037         mkdir -p $remote_dir/foo2
15038         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15039         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15040         ln $remote_dir/$tfile $remote_dir/foo1/luna
15041         ln $remote_dir/$tfile $remote_dir/foo2/thor
15042
15043         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15044                      tr -d ']')
15045         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15046                 $LFS fid2path $DIR $FID
15047                 error "bad link ea"
15048         fi
15049         # middle
15050         rm $remote_dir/foo2/zachary
15051         # last
15052         rm $remote_dir/foo2/thor
15053         # first
15054         rm $remote_dir/$tfile
15055         # rename
15056         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15057         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15058         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15059                 $LFS fid2path $DIR $FID
15060                 error "bad link rename"
15061         fi
15062         rm $remote_dir/foo2/maggie
15063
15064         # overflow the EA
15065         local longname=filename_avg_len_is_thirty_two_
15066         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15067                 error "failed to hardlink many files"
15068         links=$($LFS fid2path $DIR $FID | wc -l)
15069         echo -n "${links}/1000 links in link EA"
15070         [[ ${links} -gt 60 ]] ||
15071                 error "expected at least 60 links in link EA"
15072         unlinkmany $remote_dir/foo2/$longname 1000 ||
15073         error "failed to unlink many hardlinks"
15074 }
15075 run_test 161b "link ea sanity under remote directory"
15076
15077 test_161c() {
15078         remote_mds_nodsh && skip "remote MDS with nodsh"
15079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15080         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15081                 skip "Need MDS version at least 2.1.5"
15082
15083         # define CLF_RENAME_LAST 0x0001
15084         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15085         changelog_register || error "changelog_register failed"
15086
15087         rm -rf $DIR/$tdir
15088         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15089         touch $DIR/$tdir/foo_161c
15090         touch $DIR/$tdir/bar_161c
15091         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15092         changelog_dump | grep RENME | tail -n 5
15093         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15094         changelog_clear 0 || error "changelog_clear failed"
15095         if [ x$flags != "x0x1" ]; then
15096                 error "flag $flags is not 0x1"
15097         fi
15098
15099         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15100         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15101         touch $DIR/$tdir/foo_161c
15102         touch $DIR/$tdir/bar_161c
15103         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15104         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15105         changelog_dump | grep RENME | tail -n 5
15106         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15107         changelog_clear 0 || error "changelog_clear failed"
15108         if [ x$flags != "x0x0" ]; then
15109                 error "flag $flags is not 0x0"
15110         fi
15111         echo "rename overwrite a target having nlink > 1," \
15112                 "changelog record has flags of $flags"
15113
15114         # rename doesn't overwrite a target (changelog flag 0x0)
15115         touch $DIR/$tdir/foo_161c
15116         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15117         changelog_dump | grep RENME | tail -n 5
15118         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15119         changelog_clear 0 || error "changelog_clear failed"
15120         if [ x$flags != "x0x0" ]; then
15121                 error "flag $flags is not 0x0"
15122         fi
15123         echo "rename doesn't overwrite a target," \
15124                 "changelog record has flags of $flags"
15125
15126         # define CLF_UNLINK_LAST 0x0001
15127         # unlink a file having nlink = 1 (changelog flag 0x1)
15128         rm -f $DIR/$tdir/foo2_161c
15129         changelog_dump | grep UNLNK | tail -n 5
15130         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15131         changelog_clear 0 || error "changelog_clear failed"
15132         if [ x$flags != "x0x1" ]; then
15133                 error "flag $flags is not 0x1"
15134         fi
15135         echo "unlink a file having nlink = 1," \
15136                 "changelog record has flags of $flags"
15137
15138         # unlink a file having nlink > 1 (changelog flag 0x0)
15139         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15140         rm -f $DIR/$tdir/foobar_161c
15141         changelog_dump | grep UNLNK | tail -n 5
15142         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15143         changelog_clear 0 || error "changelog_clear failed"
15144         if [ x$flags != "x0x0" ]; then
15145                 error "flag $flags is not 0x0"
15146         fi
15147         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15148 }
15149 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15150
15151 test_161d() {
15152         remote_mds_nodsh && skip "remote MDS with nodsh"
15153         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15154
15155         local pid
15156         local fid
15157
15158         changelog_register || error "changelog_register failed"
15159
15160         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15161         # interfer with $MOUNT/.lustre/fid/ access
15162         mkdir $DIR/$tdir
15163         [[ $? -eq 0 ]] || error "mkdir failed"
15164
15165         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15166         $LCTL set_param fail_loc=0x8000140c
15167         # 5s pause
15168         $LCTL set_param fail_val=5
15169
15170         # create file
15171         echo foofoo > $DIR/$tdir/$tfile &
15172         pid=$!
15173
15174         # wait for create to be delayed
15175         sleep 2
15176
15177         ps -p $pid
15178         [[ $? -eq 0 ]] || error "create should be blocked"
15179
15180         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15181         stack_trap "rm -f $tempfile"
15182         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15183         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15184         # some delay may occur during ChangeLog publishing and file read just
15185         # above, that could allow file write to happen finally
15186         [[ -s $tempfile ]] && echo "file should be empty"
15187
15188         $LCTL set_param fail_loc=0
15189
15190         wait $pid
15191         [[ $? -eq 0 ]] || error "create failed"
15192 }
15193 run_test 161d "create with concurrent .lustre/fid access"
15194
15195 check_path() {
15196         local expected="$1"
15197         shift
15198         local fid="$2"
15199
15200         local path
15201         path=$($LFS fid2path "$@")
15202         local rc=$?
15203
15204         if [ $rc -ne 0 ]; then
15205                 error "path looked up of '$expected' failed: rc=$rc"
15206         elif [ "$path" != "$expected" ]; then
15207                 error "path looked up '$path' instead of '$expected'"
15208         else
15209                 echo "FID '$fid' resolves to path '$path' as expected"
15210         fi
15211 }
15212
15213 test_162a() { # was test_162
15214         test_mkdir -p -c1 $DIR/$tdir/d2
15215         touch $DIR/$tdir/d2/$tfile
15216         touch $DIR/$tdir/d2/x1
15217         touch $DIR/$tdir/d2/x2
15218         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15219         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15220         # regular file
15221         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15222         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15223
15224         # softlink
15225         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15226         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15227         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15228
15229         # softlink to wrong file
15230         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15231         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15232         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15233
15234         # hardlink
15235         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15236         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15237         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15238         # fid2path dir/fsname should both work
15239         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15240         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15241
15242         # hardlink count: check that there are 2 links
15243         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15244         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15245
15246         # hardlink indexing: remove the first link
15247         rm $DIR/$tdir/d2/p/q/r/hlink
15248         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15249 }
15250 run_test 162a "path lookup sanity"
15251
15252 test_162b() {
15253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15254         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15255
15256         mkdir $DIR/$tdir
15257         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15258                                 error "create striped dir failed"
15259
15260         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15261                                         tail -n 1 | awk '{print $2}')
15262         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15263
15264         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15265         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15266
15267         # regular file
15268         for ((i=0;i<5;i++)); do
15269                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15270                         error "get fid for f$i failed"
15271                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15272
15273                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15274                         error "get fid for d$i failed"
15275                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15276         done
15277
15278         return 0
15279 }
15280 run_test 162b "striped directory path lookup sanity"
15281
15282 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15283 test_162c() {
15284         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15285                 skip "Need MDS version at least 2.7.51"
15286
15287         local lpath=$tdir.local
15288         local rpath=$tdir.remote
15289
15290         test_mkdir $DIR/$lpath
15291         test_mkdir $DIR/$rpath
15292
15293         for ((i = 0; i <= 101; i++)); do
15294                 lpath="$lpath/$i"
15295                 mkdir $DIR/$lpath
15296                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15297                         error "get fid for local directory $DIR/$lpath failed"
15298                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15299
15300                 rpath="$rpath/$i"
15301                 test_mkdir $DIR/$rpath
15302                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15303                         error "get fid for remote directory $DIR/$rpath failed"
15304                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15305         done
15306
15307         return 0
15308 }
15309 run_test 162c "fid2path works with paths 100 or more directories deep"
15310
15311 oalr_event_count() {
15312         local event="${1}"
15313         local trace="${2}"
15314
15315         awk -v name="${FSNAME}-OST0000" \
15316             -v event="${event}" \
15317             '$1 == "TRACE" && $2 == event && $3 == name' \
15318             "${trace}" |
15319         wc -l
15320 }
15321
15322 oalr_expect_event_count() {
15323         local event="${1}"
15324         local trace="${2}"
15325         local expect="${3}"
15326         local count
15327
15328         count=$(oalr_event_count "${event}" "${trace}")
15329         if ((count == expect)); then
15330                 return 0
15331         fi
15332
15333         error_noexit "${event} event count was '${count}', expected ${expect}"
15334         cat "${trace}" >&2
15335         exit 1
15336 }
15337
15338 cleanup_165() {
15339         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15340         stop ost1
15341         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15342 }
15343
15344 setup_165() {
15345         sync # Flush previous IOs so we can count log entries.
15346         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15347         stack_trap cleanup_165 EXIT
15348 }
15349
15350 test_165a() {
15351         local trace="/tmp/${tfile}.trace"
15352         local rc
15353         local count
15354
15355         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15356         setup_165
15357         sleep 5
15358
15359         do_facet ost1 ofd_access_log_reader --list
15360         stop ost1
15361
15362         do_facet ost1 killall -TERM ofd_access_log_reader
15363         wait
15364         rc=$?
15365
15366         if ((rc != 0)); then
15367                 error "ofd_access_log_reader exited with rc = '${rc}'"
15368         fi
15369
15370         # Parse trace file for discovery events:
15371         oalr_expect_event_count alr_log_add "${trace}" 1
15372         oalr_expect_event_count alr_log_eof "${trace}" 1
15373         oalr_expect_event_count alr_log_free "${trace}" 1
15374 }
15375 run_test 165a "ofd access log discovery"
15376
15377 test_165b() {
15378         local trace="/tmp/${tfile}.trace"
15379         local file="${DIR}/${tfile}"
15380         local pfid1
15381         local pfid2
15382         local -a entry
15383         local rc
15384         local count
15385         local size
15386         local flags
15387
15388         setup_165
15389
15390         lfs setstripe -c 1 -i 0 "${file}"
15391         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15392         do_facet ost1 ofd_access_log_reader --list
15393
15394         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15395         sleep 5
15396         do_facet ost1 killall -TERM ofd_access_log_reader
15397         wait
15398         rc=$?
15399
15400         if ((rc != 0)); then
15401                 error "ofd_access_log_reader exited with rc = '${rc}'"
15402         fi
15403
15404         oalr_expect_event_count alr_log_entry "${trace}" 1
15405
15406         pfid1=$($LFS path2fid "${file}")
15407
15408         # 1     2             3   4    5     6   7    8    9     10
15409         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15410         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15411
15412         echo "entry = '${entry[*]}'" >&2
15413
15414         pfid2=${entry[4]}
15415         if [[ "${pfid1}" != "${pfid2}" ]]; then
15416                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15417         fi
15418
15419         size=${entry[8]}
15420         if ((size != 1048576)); then
15421                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15422         fi
15423
15424         flags=${entry[10]}
15425         if [[ "${flags}" != "w" ]]; then
15426                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15427         fi
15428
15429         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15430         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c || error "cannot read '${file}'"
15431         sleep 5
15432         do_facet ost1 killall -TERM ofd_access_log_reader
15433         wait
15434         rc=$?
15435
15436         if ((rc != 0)); then
15437                 error "ofd_access_log_reader exited with rc = '${rc}'"
15438         fi
15439
15440         oalr_expect_event_count alr_log_entry "${trace}" 1
15441
15442         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15443         echo "entry = '${entry[*]}'" >&2
15444
15445         pfid2=${entry[4]}
15446         if [[ "${pfid1}" != "${pfid2}" ]]; then
15447                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15448         fi
15449
15450         size=${entry[8]}
15451         if ((size != 524288)); then
15452                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15453         fi
15454
15455         flags=${entry[10]}
15456         if [[ "${flags}" != "r" ]]; then
15457                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15458         fi
15459 }
15460 run_test 165b "ofd access log entries are produced and consumed"
15461
15462 test_165c() {
15463         local file="${DIR}/${tdir}/${tfile}"
15464         test_mkdir "${DIR}/${tdir}"
15465
15466         setup_165
15467
15468         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
15469
15470         # 4096 / 64 = 64. Create twice as many entries.
15471         for ((i = 0; i < 128; i++)); do
15472                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c || error "cannot create file"
15473         done
15474
15475         sync
15476         do_facet ost1 ofd_access_log_reader --list
15477         unlinkmany  "${file}-%d" 128
15478 }
15479 run_test 165c "full ofd access logs do not block IOs"
15480
15481 oal_peek_entry_count() {
15482         do_facet ost1 ofd_access_log_reader --list | awk '$1 == "_entry_count:" { print $2; }'
15483 }
15484
15485 oal_expect_entry_count() {
15486         local entry_count=$(oal_peek_entry_count)
15487         local expect="$1"
15488
15489         if ((entry_count == expect)); then
15490                 return 0
15491         fi
15492
15493         error_noexit "bad entry count, got ${entry_count}, expected ${expect}"
15494         do_facet ost1 ofd_access_log_reader --list >&2
15495         exit 1
15496 }
15497
15498 test_165d() {
15499         local trace="/tmp/${tfile}.trace"
15500         local file="${DIR}/${tdir}/${tfile}"
15501         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
15502         local entry_count
15503         test_mkdir "${DIR}/${tdir}"
15504
15505         setup_165
15506         lfs setstripe -c 1 -i 0 "${file}"
15507
15508         do_facet ost1 lctl set_param "${param}=rw"
15509         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15510         oal_expect_entry_count 1
15511
15512         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15513         oal_expect_entry_count 2
15514
15515         do_facet ost1 lctl set_param "${param}=r"
15516         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15517         oal_expect_entry_count 2
15518
15519         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15520         oal_expect_entry_count 3
15521
15522         do_facet ost1 lctl set_param "${param}=w"
15523         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15524         oal_expect_entry_count 4
15525
15526         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15527         oal_expect_entry_count 4
15528
15529         do_facet ost1 lctl set_param "${param}=0"
15530         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15531         oal_expect_entry_count 4
15532
15533         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15534         oal_expect_entry_count 4
15535 }
15536 run_test 165d "ofd_access_log mask works"
15537
15538 test_169() {
15539         # do directio so as not to populate the page cache
15540         log "creating a 10 Mb file"
15541         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15542         log "starting reads"
15543         dd if=$DIR/$tfile of=/dev/null bs=4096 &
15544         log "truncating the file"
15545         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15546         log "killing dd"
15547         kill %+ || true # reads might have finished
15548         echo "wait until dd is finished"
15549         wait
15550         log "removing the temporary file"
15551         rm -rf $DIR/$tfile || error "tmp file removal failed"
15552 }
15553 run_test 169 "parallel read and truncate should not deadlock"
15554
15555 test_170() {
15556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15557
15558         $LCTL clear     # bug 18514
15559         $LCTL debug_daemon start $TMP/${tfile}_log_good
15560         touch $DIR/$tfile
15561         $LCTL debug_daemon stop
15562         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
15563                 error "sed failed to read log_good"
15564
15565         $LCTL debug_daemon start $TMP/${tfile}_log_good
15566         rm -rf $DIR/$tfile
15567         $LCTL debug_daemon stop
15568
15569         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
15570                error "lctl df log_bad failed"
15571
15572         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15573         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15574
15575         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
15576         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
15577
15578         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
15579                 error "bad_line good_line1 good_line2 are empty"
15580
15581         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15582         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
15583         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15584
15585         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
15586         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15587         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15588
15589         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
15590                 error "bad_line_new good_line_new are empty"
15591
15592         local expected_good=$((good_line1 + good_line2*2))
15593
15594         rm -f $TMP/${tfile}*
15595         # LU-231, short malformed line may not be counted into bad lines
15596         if [ $bad_line -ne $bad_line_new ] &&
15597                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
15598                 error "expected $bad_line bad lines, but got $bad_line_new"
15599                 return 1
15600         fi
15601
15602         if [ $expected_good -ne $good_line_new ]; then
15603                 error "expected $expected_good good lines, but got $good_line_new"
15604                 return 2
15605         fi
15606         true
15607 }
15608 run_test 170 "test lctl df to handle corrupted log ====================="
15609
15610 test_171() { # bug20592
15611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15612
15613         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
15614         $LCTL set_param fail_loc=0x50e
15615         $LCTL set_param fail_val=3000
15616         multiop_bg_pause $DIR/$tfile O_s || true
15617         local MULTIPID=$!
15618         kill -USR1 $MULTIPID
15619         # cause log dump
15620         sleep 3
15621         wait $MULTIPID
15622         if dmesg | grep "recursive fault"; then
15623                 error "caught a recursive fault"
15624         fi
15625         $LCTL set_param fail_loc=0
15626         true
15627 }
15628 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
15629
15630 # it would be good to share it with obdfilter-survey/iokit-libecho code
15631 setup_obdecho_osc () {
15632         local rc=0
15633         local ost_nid=$1
15634         local obdfilter_name=$2
15635         echo "Creating new osc for $obdfilter_name on $ost_nid"
15636         # make sure we can find loopback nid
15637         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
15638
15639         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
15640                            ${obdfilter_name}_osc_UUID || rc=2; }
15641         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
15642                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
15643         return $rc
15644 }
15645
15646 cleanup_obdecho_osc () {
15647         local obdfilter_name=$1
15648         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
15649         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
15650         return 0
15651 }
15652
15653 obdecho_test() {
15654         local OBD=$1
15655         local node=$2
15656         local pages=${3:-64}
15657         local rc=0
15658         local id
15659
15660         local count=10
15661         local obd_size=$(get_obd_size $node $OBD)
15662         local page_size=$(get_page_size $node)
15663         if [[ -n "$obd_size" ]]; then
15664                 local new_count=$((obd_size / (pages * page_size / 1024)))
15665                 [[ $new_count -ge $count ]] || count=$new_count
15666         fi
15667
15668         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
15669         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
15670                            rc=2; }
15671         if [ $rc -eq 0 ]; then
15672             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
15673             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
15674         fi
15675         echo "New object id is $id"
15676         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
15677                            rc=4; }
15678         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
15679                            "test_brw $count w v $pages $id" || rc=4; }
15680         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
15681                            rc=4; }
15682         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
15683                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
15684         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
15685                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
15686         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
15687         return $rc
15688 }
15689
15690 test_180a() {
15691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15692
15693         if ! module_loaded obdecho; then
15694                 load_module obdecho/obdecho &&
15695                         stack_trap "rmmod obdecho" EXIT ||
15696                         error "unable to load obdecho on client"
15697         fi
15698
15699         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
15700         local host=$($LCTL get_param -n osc.$osc.import |
15701                      awk '/current_connection:/ { print $2 }' )
15702         local target=$($LCTL get_param -n osc.$osc.import |
15703                        awk '/target:/ { print $2 }' )
15704         target=${target%_UUID}
15705
15706         if [ -n "$target" ]; then
15707                 setup_obdecho_osc $host $target &&
15708                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
15709                         { error "obdecho setup failed with $?"; return; }
15710
15711                 obdecho_test ${target}_osc client ||
15712                         error "obdecho_test failed on ${target}_osc"
15713         else
15714                 $LCTL get_param osc.$osc.import
15715                 error "there is no osc.$osc.import target"
15716         fi
15717 }
15718 run_test 180a "test obdecho on osc"
15719
15720 test_180b() {
15721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15722         remote_ost_nodsh && skip "remote OST with nodsh"
15723
15724         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15725                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15726                 error "failed to load module obdecho"
15727
15728         local target=$(do_facet ost1 $LCTL dl |
15729                        awk '/obdfilter/ { print $4; exit; }')
15730
15731         if [ -n "$target" ]; then
15732                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
15733         else
15734                 do_facet ost1 $LCTL dl
15735                 error "there is no obdfilter target on ost1"
15736         fi
15737 }
15738 run_test 180b "test obdecho directly on obdfilter"
15739
15740 test_180c() { # LU-2598
15741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15742         remote_ost_nodsh && skip "remote OST with nodsh"
15743         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
15744                 skip "Need MDS version at least 2.4.0"
15745
15746         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15747                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15748                 error "failed to load module obdecho"
15749
15750         local target=$(do_facet ost1 $LCTL dl |
15751                        awk '/obdfilter/ { print $4; exit; }')
15752
15753         if [ -n "$target" ]; then
15754                 local pages=16384 # 64MB bulk I/O RPC size
15755
15756                 obdecho_test "$target" ost1 "$pages" ||
15757                         error "obdecho_test with pages=$pages failed with $?"
15758         else
15759                 do_facet ost1 $LCTL dl
15760                 error "there is no obdfilter target on ost1"
15761         fi
15762 }
15763 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
15764
15765 test_181() { # bug 22177
15766         test_mkdir $DIR/$tdir
15767         # create enough files to index the directory
15768         createmany -o $DIR/$tdir/foobar 4000
15769         # print attributes for debug purpose
15770         lsattr -d .
15771         # open dir
15772         multiop_bg_pause $DIR/$tdir D_Sc || return 1
15773         MULTIPID=$!
15774         # remove the files & current working dir
15775         unlinkmany $DIR/$tdir/foobar 4000
15776         rmdir $DIR/$tdir
15777         kill -USR1 $MULTIPID
15778         wait $MULTIPID
15779         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
15780         return 0
15781 }
15782 run_test 181 "Test open-unlinked dir ========================"
15783
15784 test_182() {
15785         local fcount=1000
15786         local tcount=10
15787
15788         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15789
15790         $LCTL set_param mdc.*.rpc_stats=clear
15791
15792         for (( i = 0; i < $tcount; i++ )) ; do
15793                 mkdir $DIR/$tdir/$i
15794         done
15795
15796         for (( i = 0; i < $tcount; i++ )) ; do
15797                 createmany -o $DIR/$tdir/$i/f- $fcount &
15798         done
15799         wait
15800
15801         for (( i = 0; i < $tcount; i++ )) ; do
15802                 unlinkmany $DIR/$tdir/$i/f- $fcount &
15803         done
15804         wait
15805
15806         $LCTL get_param mdc.*.rpc_stats
15807
15808         rm -rf $DIR/$tdir
15809 }
15810 run_test 182 "Test parallel modify metadata operations ================"
15811
15812 test_183() { # LU-2275
15813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15814         remote_mds_nodsh && skip "remote MDS with nodsh"
15815         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
15816                 skip "Need MDS version at least 2.3.56"
15817
15818         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15819         echo aaa > $DIR/$tdir/$tfile
15820
15821 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
15822         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
15823
15824         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
15825         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
15826
15827         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
15828
15829         # Flush negative dentry cache
15830         touch $DIR/$tdir/$tfile
15831
15832         # We are not checking for any leaked references here, they'll
15833         # become evident next time we do cleanup with module unload.
15834         rm -rf $DIR/$tdir
15835 }
15836 run_test 183 "No crash or request leak in case of strange dispositions ========"
15837
15838 # test suite 184 is for LU-2016, LU-2017
15839 test_184a() {
15840         check_swap_layouts_support
15841
15842         dir0=$DIR/$tdir/$testnum
15843         test_mkdir -p -c1 $dir0
15844         ref1=/etc/passwd
15845         ref2=/etc/group
15846         file1=$dir0/f1
15847         file2=$dir0/f2
15848         $LFS setstripe -c1 $file1
15849         cp $ref1 $file1
15850         $LFS setstripe -c2 $file2
15851         cp $ref2 $file2
15852         gen1=$($LFS getstripe -g $file1)
15853         gen2=$($LFS getstripe -g $file2)
15854
15855         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
15856         gen=$($LFS getstripe -g $file1)
15857         [[ $gen1 != $gen ]] ||
15858                 "Layout generation on $file1 does not change"
15859         gen=$($LFS getstripe -g $file2)
15860         [[ $gen2 != $gen ]] ||
15861                 "Layout generation on $file2 does not change"
15862
15863         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
15864         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
15865
15866         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
15867 }
15868 run_test 184a "Basic layout swap"
15869
15870 test_184b() {
15871         check_swap_layouts_support
15872
15873         dir0=$DIR/$tdir/$testnum
15874         mkdir -p $dir0 || error "creating dir $dir0"
15875         file1=$dir0/f1
15876         file2=$dir0/f2
15877         file3=$dir0/f3
15878         dir1=$dir0/d1
15879         dir2=$dir0/d2
15880         mkdir $dir1 $dir2
15881         $LFS setstripe -c1 $file1
15882         $LFS setstripe -c2 $file2
15883         $LFS setstripe -c1 $file3
15884         chown $RUNAS_ID $file3
15885         gen1=$($LFS getstripe -g $file1)
15886         gen2=$($LFS getstripe -g $file2)
15887
15888         $LFS swap_layouts $dir1 $dir2 &&
15889                 error "swap of directories layouts should fail"
15890         $LFS swap_layouts $dir1 $file1 &&
15891                 error "swap of directory and file layouts should fail"
15892         $RUNAS $LFS swap_layouts $file1 $file2 &&
15893                 error "swap of file we cannot write should fail"
15894         $LFS swap_layouts $file1 $file3 &&
15895                 error "swap of file with different owner should fail"
15896         /bin/true # to clear error code
15897 }
15898 run_test 184b "Forbidden layout swap (will generate errors)"
15899
15900 test_184c() {
15901         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
15902         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
15903         check_swap_layouts_support
15904         check_swap_layout_no_dom $DIR
15905
15906         local dir0=$DIR/$tdir/$testnum
15907         mkdir -p $dir0 || error "creating dir $dir0"
15908
15909         local ref1=$dir0/ref1
15910         local ref2=$dir0/ref2
15911         local file1=$dir0/file1
15912         local file2=$dir0/file2
15913         # create a file large enough for the concurrent test
15914         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
15915         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
15916         echo "ref file size: ref1($(stat -c %s $ref1))," \
15917              "ref2($(stat -c %s $ref2))"
15918
15919         cp $ref2 $file2
15920         dd if=$ref1 of=$file1 bs=16k &
15921         local DD_PID=$!
15922
15923         # Make sure dd starts to copy file
15924         while [ ! -f $file1 ]; do sleep 0.1; done
15925
15926         $LFS swap_layouts $file1 $file2
15927         local rc=$?
15928         wait $DD_PID
15929         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
15930         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
15931
15932         # how many bytes copied before swapping layout
15933         local copied=$(stat -c %s $file2)
15934         local remaining=$(stat -c %s $ref1)
15935         remaining=$((remaining - copied))
15936         echo "Copied $copied bytes before swapping layout..."
15937
15938         cmp -n $copied $file1 $ref2 | grep differ &&
15939                 error "Content mismatch [0, $copied) of ref2 and file1"
15940         cmp -n $copied $file2 $ref1 ||
15941                 error "Content mismatch [0, $copied) of ref1 and file2"
15942         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
15943                 error "Content mismatch [$copied, EOF) of ref1 and file1"
15944
15945         # clean up
15946         rm -f $ref1 $ref2 $file1 $file2
15947 }
15948 run_test 184c "Concurrent write and layout swap"
15949
15950 test_184d() {
15951         check_swap_layouts_support
15952         check_swap_layout_no_dom $DIR
15953         [ -z "$(which getfattr 2>/dev/null)" ] &&
15954                 skip_env "no getfattr command"
15955
15956         local file1=$DIR/$tdir/$tfile-1
15957         local file2=$DIR/$tdir/$tfile-2
15958         local file3=$DIR/$tdir/$tfile-3
15959         local lovea1
15960         local lovea2
15961
15962         mkdir -p $DIR/$tdir
15963         touch $file1 || error "create $file1 failed"
15964         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
15965                 error "create $file2 failed"
15966         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
15967                 error "create $file3 failed"
15968         lovea1=$(get_layout_param $file1)
15969
15970         $LFS swap_layouts $file2 $file3 ||
15971                 error "swap $file2 $file3 layouts failed"
15972         $LFS swap_layouts $file1 $file2 ||
15973                 error "swap $file1 $file2 layouts failed"
15974
15975         lovea2=$(get_layout_param $file2)
15976         echo "$lovea1"
15977         echo "$lovea2"
15978         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
15979
15980         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
15981         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
15982 }
15983 run_test 184d "allow stripeless layouts swap"
15984
15985 test_184e() {
15986         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
15987                 skip "Need MDS version at least 2.6.94"
15988         check_swap_layouts_support
15989         check_swap_layout_no_dom $DIR
15990         [ -z "$(which getfattr 2>/dev/null)" ] &&
15991                 skip_env "no getfattr command"
15992
15993         local file1=$DIR/$tdir/$tfile-1
15994         local file2=$DIR/$tdir/$tfile-2
15995         local file3=$DIR/$tdir/$tfile-3
15996         local lovea
15997
15998         mkdir -p $DIR/$tdir
15999         touch $file1 || error "create $file1 failed"
16000         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16001                 error "create $file2 failed"
16002         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16003                 error "create $file3 failed"
16004
16005         $LFS swap_layouts $file1 $file2 ||
16006                 error "swap $file1 $file2 layouts failed"
16007
16008         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16009         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16010
16011         echo 123 > $file1 || error "Should be able to write into $file1"
16012
16013         $LFS swap_layouts $file1 $file3 ||
16014                 error "swap $file1 $file3 layouts failed"
16015
16016         echo 123 > $file1 || error "Should be able to write into $file1"
16017
16018         rm -rf $file1 $file2 $file3
16019 }
16020 run_test 184e "Recreate layout after stripeless layout swaps"
16021
16022 test_184f() {
16023         # Create a file with name longer than sizeof(struct stat) ==
16024         # 144 to see if we can get chars from the file name to appear
16025         # in the returned striping. Note that 'f' == 0x66.
16026         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16027
16028         mkdir -p $DIR/$tdir
16029         mcreate $DIR/$tdir/$file
16030         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16031                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16032         fi
16033 }
16034 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16035
16036 test_185() { # LU-2441
16037         # LU-3553 - no volatile file support in old servers
16038         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16039                 skip "Need MDS version at least 2.3.60"
16040
16041         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16042         touch $DIR/$tdir/spoo
16043         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16044         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16045                 error "cannot create/write a volatile file"
16046         [ "$FILESET" == "" ] &&
16047         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16048                 error "FID is still valid after close"
16049
16050         multiop_bg_pause $DIR/$tdir vVw4096_c
16051         local multi_pid=$!
16052
16053         local OLD_IFS=$IFS
16054         IFS=":"
16055         local fidv=($fid)
16056         IFS=$OLD_IFS
16057         # assume that the next FID for this client is sequential, since stdout
16058         # is unfortunately eaten by multiop_bg_pause
16059         local n=$((${fidv[1]} + 1))
16060         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16061         if [ "$FILESET" == "" ]; then
16062                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16063                         error "FID is missing before close"
16064         fi
16065         kill -USR1 $multi_pid
16066         # 1 second delay, so if mtime change we will see it
16067         sleep 1
16068         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16069         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16070 }
16071 run_test 185 "Volatile file support"
16072
16073 function create_check_volatile() {
16074         local idx=$1
16075         local tgt
16076
16077         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16078         local PID=$!
16079         sleep 1
16080         local FID=$(cat /tmp/${tfile}.fid)
16081         [ "$FID" == "" ] && error "can't get FID for volatile"
16082         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16083         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16084         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16085         kill -USR1 $PID
16086         wait
16087         sleep 1
16088         cancel_lru_locks mdc # flush opencache
16089         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16090         return 0
16091 }
16092
16093 test_185a(){
16094         # LU-12516 - volatile creation via .lustre
16095         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16096                 skip "Need MDS version at least 2.3.55"
16097
16098         create_check_volatile 0
16099         [ $MDSCOUNT -lt 2 ] && return 0
16100
16101         # DNE case
16102         create_check_volatile 1
16103
16104         return 0
16105 }
16106 run_test 185a "Volatile file creation in .lustre/fid/"
16107
16108 test_187a() {
16109         remote_mds_nodsh && skip "remote MDS with nodsh"
16110         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16111                 skip "Need MDS version at least 2.3.0"
16112
16113         local dir0=$DIR/$tdir/$testnum
16114         mkdir -p $dir0 || error "creating dir $dir0"
16115
16116         local file=$dir0/file1
16117         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16118         local dv1=$($LFS data_version $file)
16119         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16120         local dv2=$($LFS data_version $file)
16121         [[ $dv1 != $dv2 ]] ||
16122                 error "data version did not change on write $dv1 == $dv2"
16123
16124         # clean up
16125         rm -f $file1
16126 }
16127 run_test 187a "Test data version change"
16128
16129 test_187b() {
16130         remote_mds_nodsh && skip "remote MDS with nodsh"
16131         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16132                 skip "Need MDS version at least 2.3.0"
16133
16134         local dir0=$DIR/$tdir/$testnum
16135         mkdir -p $dir0 || error "creating dir $dir0"
16136
16137         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16138         [[ ${DV[0]} != ${DV[1]} ]] ||
16139                 error "data version did not change on write"\
16140                       " ${DV[0]} == ${DV[1]}"
16141
16142         # clean up
16143         rm -f $file1
16144 }
16145 run_test 187b "Test data version change on volatile file"
16146
16147 test_200() {
16148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16149         remote_mgs_nodsh && skip "remote MGS with nodsh"
16150         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16151
16152         local POOL=${POOL:-cea1}
16153         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16154         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16155         # Pool OST targets
16156         local first_ost=0
16157         local last_ost=$(($OSTCOUNT - 1))
16158         local ost_step=2
16159         local ost_list=$(seq $first_ost $ost_step $last_ost)
16160         local ost_range="$first_ost $last_ost $ost_step"
16161         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16162         local file_dir=$POOL_ROOT/file_tst
16163         local subdir=$test_path/subdir
16164         local rc=0
16165
16166         while : ; do
16167                 # former test_200a test_200b
16168                 pool_add $POOL                          || { rc=$? ; break; }
16169                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16170                 # former test_200c test_200d
16171                 mkdir -p $test_path
16172                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16173                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16174                 mkdir -p $subdir
16175                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16176                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16177                                                         || { rc=$? ; break; }
16178                 # former test_200e test_200f
16179                 local files=$((OSTCOUNT*3))
16180                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16181                                                         || { rc=$? ; break; }
16182                 pool_create_files $POOL $file_dir $files "$ost_list" \
16183                                                         || { rc=$? ; break; }
16184                 # former test_200g test_200h
16185                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16186                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16187
16188                 # former test_201a test_201b test_201c
16189                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16190
16191                 local f=$test_path/$tfile
16192                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16193                 pool_remove $POOL $f                    || { rc=$? ; break; }
16194                 break
16195         done
16196
16197         destroy_test_pools
16198
16199         return $rc
16200 }
16201 run_test 200 "OST pools"
16202
16203 # usage: default_attr <count | size | offset>
16204 default_attr() {
16205         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16206 }
16207
16208 # usage: check_default_stripe_attr
16209 check_default_stripe_attr() {
16210         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16211         case $1 in
16212         --stripe-count|-c)
16213                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16214         --stripe-size|-S)
16215                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16216         --stripe-index|-i)
16217                 EXPECTED=-1;;
16218         *)
16219                 error "unknown getstripe attr '$1'"
16220         esac
16221
16222         [ $ACTUAL == $EXPECTED ] ||
16223                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16224 }
16225
16226 test_204a() {
16227         test_mkdir $DIR/$tdir
16228         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16229
16230         check_default_stripe_attr --stripe-count
16231         check_default_stripe_attr --stripe-size
16232         check_default_stripe_attr --stripe-index
16233 }
16234 run_test 204a "Print default stripe attributes"
16235
16236 test_204b() {
16237         test_mkdir $DIR/$tdir
16238         $LFS setstripe --stripe-count 1 $DIR/$tdir
16239
16240         check_default_stripe_attr --stripe-size
16241         check_default_stripe_attr --stripe-index
16242 }
16243 run_test 204b "Print default stripe size and offset"
16244
16245 test_204c() {
16246         test_mkdir $DIR/$tdir
16247         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16248
16249         check_default_stripe_attr --stripe-count
16250         check_default_stripe_attr --stripe-index
16251 }
16252 run_test 204c "Print default stripe count and offset"
16253
16254 test_204d() {
16255         test_mkdir $DIR/$tdir
16256         $LFS setstripe --stripe-index 0 $DIR/$tdir
16257
16258         check_default_stripe_attr --stripe-count
16259         check_default_stripe_attr --stripe-size
16260 }
16261 run_test 204d "Print default stripe count and size"
16262
16263 test_204e() {
16264         test_mkdir $DIR/$tdir
16265         $LFS setstripe -d $DIR/$tdir
16266
16267         check_default_stripe_attr --stripe-count --raw
16268         check_default_stripe_attr --stripe-size --raw
16269         check_default_stripe_attr --stripe-index --raw
16270 }
16271 run_test 204e "Print raw stripe attributes"
16272
16273 test_204f() {
16274         test_mkdir $DIR/$tdir
16275         $LFS setstripe --stripe-count 1 $DIR/$tdir
16276
16277         check_default_stripe_attr --stripe-size --raw
16278         check_default_stripe_attr --stripe-index --raw
16279 }
16280 run_test 204f "Print raw stripe size and offset"
16281
16282 test_204g() {
16283         test_mkdir $DIR/$tdir
16284         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16285
16286         check_default_stripe_attr --stripe-count --raw
16287         check_default_stripe_attr --stripe-index --raw
16288 }
16289 run_test 204g "Print raw stripe count and offset"
16290
16291 test_204h() {
16292         test_mkdir $DIR/$tdir
16293         $LFS setstripe --stripe-index 0 $DIR/$tdir
16294
16295         check_default_stripe_attr --stripe-count --raw
16296         check_default_stripe_attr --stripe-size --raw
16297 }
16298 run_test 204h "Print raw stripe count and size"
16299
16300 # Figure out which job scheduler is being used, if any,
16301 # or use a fake one
16302 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16303         JOBENV=SLURM_JOB_ID
16304 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16305         JOBENV=LSB_JOBID
16306 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16307         JOBENV=PBS_JOBID
16308 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16309         JOBENV=LOADL_STEP_ID
16310 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16311         JOBENV=JOB_ID
16312 else
16313         $LCTL list_param jobid_name > /dev/null 2>&1
16314         if [ $? -eq 0 ]; then
16315                 JOBENV=nodelocal
16316         else
16317                 JOBENV=FAKE_JOBID
16318         fi
16319 fi
16320 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16321
16322 verify_jobstats() {
16323         local cmd=($1)
16324         shift
16325         local facets="$@"
16326
16327 # we don't really need to clear the stats for this test to work, since each
16328 # command has a unique jobid, but it makes debugging easier if needed.
16329 #       for facet in $facets; do
16330 #               local dev=$(convert_facet2label $facet)
16331 #               # clear old jobstats
16332 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16333 #       done
16334
16335         # use a new JobID for each test, or we might see an old one
16336         [ "$JOBENV" = "FAKE_JOBID" ] &&
16337                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16338
16339         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16340
16341         [ "$JOBENV" = "nodelocal" ] && {
16342                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16343                 $LCTL set_param jobid_name=$FAKE_JOBID
16344                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16345         }
16346
16347         log "Test: ${cmd[*]}"
16348         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16349
16350         if [ $JOBENV = "FAKE_JOBID" ]; then
16351                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16352         else
16353                 ${cmd[*]}
16354         fi
16355
16356         # all files are created on OST0000
16357         for facet in $facets; do
16358                 local stats="*.$(convert_facet2label $facet).job_stats"
16359
16360                 # strip out libtool wrappers for in-tree executables
16361                 if [ $(do_facet $facet lctl get_param $stats |
16362                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16363                         do_facet $facet lctl get_param $stats
16364                         error "No jobstats for $JOBVAL found on $facet::$stats"
16365                 fi
16366         done
16367 }
16368
16369 jobstats_set() {
16370         local new_jobenv=$1
16371
16372         set_persistent_param_and_check client "jobid_var" \
16373                 "$FSNAME.sys.jobid_var" $new_jobenv
16374 }
16375
16376 test_205a() { # Job stats
16377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16378         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
16379                 skip "Need MDS version with at least 2.7.1"
16380         remote_mgs_nodsh && skip "remote MGS with nodsh"
16381         remote_mds_nodsh && skip "remote MDS with nodsh"
16382         remote_ost_nodsh && skip "remote OST with nodsh"
16383         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
16384                 skip "Server doesn't support jobstats"
16385         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
16386
16387         local old_jobenv=$($LCTL get_param -n jobid_var)
16388         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
16389
16390         if [[ $PERM_CMD == *"set_param -P"* ]]; then
16391                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
16392         else
16393                 stack_trap "do_facet mgs $PERM_CMD \
16394                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
16395         fi
16396         changelog_register
16397
16398         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
16399                                 mdt.*.job_cleanup_interval | head -n 1)
16400         local new_interval=5
16401         do_facet $SINGLEMDS \
16402                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
16403         stack_trap "do_facet $SINGLEMDS \
16404                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
16405         local start=$SECONDS
16406
16407         local cmd
16408         # mkdir
16409         cmd="mkdir $DIR/$tdir"
16410         verify_jobstats "$cmd" "$SINGLEMDS"
16411         # rmdir
16412         cmd="rmdir $DIR/$tdir"
16413         verify_jobstats "$cmd" "$SINGLEMDS"
16414         # mkdir on secondary MDT
16415         if [ $MDSCOUNT -gt 1 ]; then
16416                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
16417                 verify_jobstats "$cmd" "mds2"
16418         fi
16419         # mknod
16420         cmd="mknod $DIR/$tfile c 1 3"
16421         verify_jobstats "$cmd" "$SINGLEMDS"
16422         # unlink
16423         cmd="rm -f $DIR/$tfile"
16424         verify_jobstats "$cmd" "$SINGLEMDS"
16425         # create all files on OST0000 so verify_jobstats can find OST stats
16426         # open & close
16427         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
16428         verify_jobstats "$cmd" "$SINGLEMDS"
16429         # setattr
16430         cmd="touch $DIR/$tfile"
16431         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16432         # write
16433         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
16434         verify_jobstats "$cmd" "ost1"
16435         # read
16436         cancel_lru_locks osc
16437         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
16438         verify_jobstats "$cmd" "ost1"
16439         # truncate
16440         cmd="$TRUNCATE $DIR/$tfile 0"
16441         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16442         # rename
16443         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
16444         verify_jobstats "$cmd" "$SINGLEMDS"
16445         # jobstats expiry - sleep until old stats should be expired
16446         local left=$((new_interval + 5 - (SECONDS - start)))
16447         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
16448                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
16449                         "0" $left
16450         cmd="mkdir $DIR/$tdir.expire"
16451         verify_jobstats "$cmd" "$SINGLEMDS"
16452         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
16453             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
16454
16455         # Ensure that jobid are present in changelog (if supported by MDS)
16456         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
16457                 changelog_dump | tail -10
16458                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
16459                 [ $jobids -eq 9 ] ||
16460                         error "Wrong changelog jobid count $jobids != 9"
16461
16462                 # LU-5862
16463                 JOBENV="disable"
16464                 jobstats_set $JOBENV
16465                 touch $DIR/$tfile
16466                 changelog_dump | grep $tfile
16467                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
16468                 [ $jobids -eq 0 ] ||
16469                         error "Unexpected jobids when jobid_var=$JOBENV"
16470         fi
16471
16472         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
16473         JOBENV="JOBCOMPLEX"
16474         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16475
16476         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16477 }
16478 run_test 205a "Verify job stats"
16479
16480 # LU-13117, LU-13597
16481 test_205b() {
16482         job_stats="mdt.*.job_stats"
16483         $LCTL set_param $job_stats=clear
16484         $LCTL set_param jobid_var=USER jobid_name="%e.%u"
16485         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16486         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16487                 grep "job_id:.*foolish" &&
16488                         error "Unexpected jobid found"
16489         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16490                 grep "open:.*min.*max.*sum" ||
16491                         error "wrong job_stats format found"
16492 }
16493 run_test 205b "Verify job stats jobid and output format"
16494
16495 # LU-1480, LU-1773 and LU-1657
16496 test_206() {
16497         mkdir -p $DIR/$tdir
16498         $LFS setstripe -c -1 $DIR/$tdir
16499 #define OBD_FAIL_LOV_INIT 0x1403
16500         $LCTL set_param fail_loc=0xa0001403
16501         $LCTL set_param fail_val=1
16502         touch $DIR/$tdir/$tfile || true
16503 }
16504 run_test 206 "fail lov_init_raid0() doesn't lbug"
16505
16506 test_207a() {
16507         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16508         local fsz=`stat -c %s $DIR/$tfile`
16509         cancel_lru_locks mdc
16510
16511         # do not return layout in getattr intent
16512 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16513         $LCTL set_param fail_loc=0x170
16514         local sz=`stat -c %s $DIR/$tfile`
16515
16516         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16517
16518         rm -rf $DIR/$tfile
16519 }
16520 run_test 207a "can refresh layout at glimpse"
16521
16522 test_207b() {
16523         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16524         local cksum=`md5sum $DIR/$tfile`
16525         local fsz=`stat -c %s $DIR/$tfile`
16526         cancel_lru_locks mdc
16527         cancel_lru_locks osc
16528
16529         # do not return layout in getattr intent
16530 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16531         $LCTL set_param fail_loc=0x171
16532
16533         # it will refresh layout after the file is opened but before read issues
16534         echo checksum is "$cksum"
16535         echo "$cksum" |md5sum -c --quiet || error "file differs"
16536
16537         rm -rf $DIR/$tfile
16538 }
16539 run_test 207b "can refresh layout at open"
16540
16541 test_208() {
16542         # FIXME: in this test suite, only RD lease is used. This is okay
16543         # for now as only exclusive open is supported. After generic lease
16544         # is done, this test suite should be revised. - Jinshan
16545
16546         remote_mds_nodsh && skip "remote MDS with nodsh"
16547         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
16548                 skip "Need MDS version at least 2.4.52"
16549
16550         echo "==== test 1: verify get lease work"
16551         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
16552
16553         echo "==== test 2: verify lease can be broken by upcoming open"
16554         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16555         local PID=$!
16556         sleep 1
16557
16558         $MULTIOP $DIR/$tfile oO_RDONLY:c
16559         kill -USR1 $PID && wait $PID || error "break lease error"
16560
16561         echo "==== test 3: verify lease can't be granted if an open already exists"
16562         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
16563         local PID=$!
16564         sleep 1
16565
16566         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
16567         kill -USR1 $PID && wait $PID || error "open file error"
16568
16569         echo "==== test 4: lease can sustain over recovery"
16570         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16571         PID=$!
16572         sleep 1
16573
16574         fail mds1
16575
16576         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
16577
16578         echo "==== test 5: lease broken can't be regained by replay"
16579         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16580         PID=$!
16581         sleep 1
16582
16583         # open file to break lease and then recovery
16584         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
16585         fail mds1
16586
16587         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
16588
16589         rm -f $DIR/$tfile
16590 }
16591 run_test 208 "Exclusive open"
16592
16593 test_209() {
16594         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
16595                 skip_env "must have disp_stripe"
16596
16597         touch $DIR/$tfile
16598         sync; sleep 5; sync;
16599
16600         echo 3 > /proc/sys/vm/drop_caches
16601         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16602                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16603         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16604
16605         # open/close 500 times
16606         for i in $(seq 500); do
16607                 cat $DIR/$tfile
16608         done
16609
16610         echo 3 > /proc/sys/vm/drop_caches
16611         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16612                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16613         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16614
16615         echo "before: $req_before, after: $req_after"
16616         [ $((req_after - req_before)) -ge 300 ] &&
16617                 error "open/close requests are not freed"
16618         return 0
16619 }
16620 run_test 209 "read-only open/close requests should be freed promptly"
16621
16622 test_210() {
16623         local pid
16624
16625         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
16626         pid=$!
16627         sleep 1
16628
16629         $LFS getstripe $DIR/$tfile
16630         kill -USR1 $pid
16631         wait $pid || error "multiop failed"
16632
16633         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16634         pid=$!
16635         sleep 1
16636
16637         $LFS getstripe $DIR/$tfile
16638         kill -USR1 $pid
16639         wait $pid || error "multiop failed"
16640 }
16641 run_test 210 "lfs getstripe does not break leases"
16642
16643 test_212() {
16644         size=`date +%s`
16645         size=$((size % 8192 + 1))
16646         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
16647         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
16648         rm -f $DIR/f212 $DIR/f212.xyz
16649 }
16650 run_test 212 "Sendfile test ============================================"
16651
16652 test_213() {
16653         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
16654         cancel_lru_locks osc
16655         lctl set_param fail_loc=0x8000040f
16656         # generate a read lock
16657         cat $DIR/$tfile > /dev/null
16658         # write to the file, it will try to cancel the above read lock.
16659         cat /etc/hosts >> $DIR/$tfile
16660 }
16661 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
16662
16663 test_214() { # for bug 20133
16664         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
16665         for (( i=0; i < 340; i++ )) ; do
16666                 touch $DIR/$tdir/d214c/a$i
16667         done
16668
16669         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
16670         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
16671         ls $DIR/d214c || error "ls $DIR/d214c failed"
16672         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
16673         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
16674 }
16675 run_test 214 "hash-indexed directory test - bug 20133"
16676
16677 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
16678 create_lnet_proc_files() {
16679         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
16680 }
16681
16682 # counterpart of create_lnet_proc_files
16683 remove_lnet_proc_files() {
16684         rm -f $TMP/lnet_$1.sys
16685 }
16686
16687 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16688 # 3rd arg as regexp for body
16689 check_lnet_proc_stats() {
16690         local l=$(cat "$TMP/lnet_$1" |wc -l)
16691         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
16692
16693         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
16694 }
16695
16696 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16697 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
16698 # optional and can be regexp for 2nd line (lnet.routes case)
16699 check_lnet_proc_entry() {
16700         local blp=2          # blp stands for 'position of 1st line of body'
16701         [ -z "$5" ] || blp=3 # lnet.routes case
16702
16703         local l=$(cat "$TMP/lnet_$1" |wc -l)
16704         # subtracting one from $blp because the body can be empty
16705         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
16706
16707         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
16708                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
16709
16710         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
16711                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
16712
16713         # bail out if any unexpected line happened
16714         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
16715         [ "$?" != 0 ] || error "$2 misformatted"
16716 }
16717
16718 test_215() { # for bugs 18102, 21079, 21517
16719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16720
16721         local N='(0|[1-9][0-9]*)'       # non-negative numeric
16722         local P='[1-9][0-9]*'           # positive numeric
16723         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
16724         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
16725         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
16726         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
16727
16728         local L1 # regexp for 1st line
16729         local L2 # regexp for 2nd line (optional)
16730         local BR # regexp for the rest (body)
16731
16732         # lnet.stats should look as 11 space-separated non-negative numerics
16733         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
16734         create_lnet_proc_files "stats"
16735         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
16736         remove_lnet_proc_files "stats"
16737
16738         # lnet.routes should look like this:
16739         # Routing disabled/enabled
16740         # net hops priority state router
16741         # where net is a string like tcp0, hops > 0, priority >= 0,
16742         # state is up/down,
16743         # router is a string like 192.168.1.1@tcp2
16744         L1="^Routing (disabled|enabled)$"
16745         L2="^net +hops +priority +state +router$"
16746         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
16747         create_lnet_proc_files "routes"
16748         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
16749         remove_lnet_proc_files "routes"
16750
16751         # lnet.routers should look like this:
16752         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
16753         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
16754         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
16755         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
16756         L1="^ref +rtr_ref +alive +router$"
16757         BR="^$P +$P +(up|down) +$NID$"
16758         create_lnet_proc_files "routers"
16759         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
16760         remove_lnet_proc_files "routers"
16761
16762         # lnet.peers should look like this:
16763         # nid refs state last max rtr min tx min queue
16764         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
16765         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
16766         # numeric (0 or >0 or <0), queue >= 0.
16767         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
16768         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
16769         create_lnet_proc_files "peers"
16770         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
16771         remove_lnet_proc_files "peers"
16772
16773         # lnet.buffers  should look like this:
16774         # pages count credits min
16775         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
16776         L1="^pages +count +credits +min$"
16777         BR="^ +$N +$N +$I +$I$"
16778         create_lnet_proc_files "buffers"
16779         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
16780         remove_lnet_proc_files "buffers"
16781
16782         # lnet.nis should look like this:
16783         # nid status alive refs peer rtr max tx min
16784         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
16785         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
16786         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
16787         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
16788         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
16789         create_lnet_proc_files "nis"
16790         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
16791         remove_lnet_proc_files "nis"
16792
16793         # can we successfully write to lnet.stats?
16794         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
16795 }
16796 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
16797
16798 test_216() { # bug 20317
16799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16800         remote_ost_nodsh && skip "remote OST with nodsh"
16801
16802         local node
16803         local facets=$(get_facets OST)
16804         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16805
16806         save_lustre_params client "osc.*.contention_seconds" > $p
16807         save_lustre_params $facets \
16808                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
16809         save_lustre_params $facets \
16810                 "ldlm.namespaces.filter-*.contended_locks" >> $p
16811         save_lustre_params $facets \
16812                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
16813         clear_stats osc.*.osc_stats
16814
16815         # agressive lockless i/o settings
16816         do_nodes $(comma_list $(osts_nodes)) \
16817                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
16818                         ldlm.namespaces.filter-*.contended_locks=0 \
16819                         ldlm.namespaces.filter-*.contention_seconds=60"
16820         lctl set_param -n osc.*.contention_seconds=60
16821
16822         $DIRECTIO write $DIR/$tfile 0 10 4096
16823         $CHECKSTAT -s 40960 $DIR/$tfile
16824
16825         # disable lockless i/o
16826         do_nodes $(comma_list $(osts_nodes)) \
16827                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
16828                         ldlm.namespaces.filter-*.contended_locks=32 \
16829                         ldlm.namespaces.filter-*.contention_seconds=0"
16830         lctl set_param -n osc.*.contention_seconds=0
16831         clear_stats osc.*.osc_stats
16832
16833         dd if=/dev/zero of=$DIR/$tfile count=0
16834         $CHECKSTAT -s 0 $DIR/$tfile
16835
16836         restore_lustre_params <$p
16837         rm -f $p
16838         rm $DIR/$tfile
16839 }
16840 run_test 216 "check lockless direct write updates file size and kms correctly"
16841
16842 test_217() { # bug 22430
16843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16844
16845         local node
16846         local nid
16847
16848         for node in $(nodes_list); do
16849                 nid=$(host_nids_address $node $NETTYPE)
16850                 if [[ $nid = *-* ]] ; then
16851                         echo "lctl ping $(h2nettype $nid)"
16852                         lctl ping $(h2nettype $nid)
16853                 else
16854                         echo "skipping $node (no hyphen detected)"
16855                 fi
16856         done
16857 }
16858 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
16859
16860 test_218() {
16861        # do directio so as not to populate the page cache
16862        log "creating a 10 Mb file"
16863        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
16864        log "starting reads"
16865        dd if=$DIR/$tfile of=/dev/null bs=4096 &
16866        log "truncating the file"
16867        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
16868        log "killing dd"
16869        kill %+ || true # reads might have finished
16870        echo "wait until dd is finished"
16871        wait
16872        log "removing the temporary file"
16873        rm -rf $DIR/$tfile || error "tmp file removal failed"
16874 }
16875 run_test 218 "parallel read and truncate should not deadlock"
16876
16877 test_219() {
16878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16879
16880         # write one partial page
16881         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
16882         # set no grant so vvp_io_commit_write will do sync write
16883         $LCTL set_param fail_loc=0x411
16884         # write a full page at the end of file
16885         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
16886
16887         $LCTL set_param fail_loc=0
16888         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
16889         $LCTL set_param fail_loc=0x411
16890         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
16891
16892         # LU-4201
16893         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
16894         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
16895 }
16896 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
16897
16898 test_220() { #LU-325
16899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16900         remote_ost_nodsh && skip "remote OST with nodsh"
16901         remote_mds_nodsh && skip "remote MDS with nodsh"
16902         remote_mgs_nodsh && skip "remote MGS with nodsh"
16903
16904         local OSTIDX=0
16905
16906         # create on MDT0000 so the last_id and next_id are correct
16907         mkdir $DIR/$tdir
16908         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
16909         OST=${OST%_UUID}
16910
16911         # on the mdt's osc
16912         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
16913         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
16914                         osp.$mdtosc_proc1.prealloc_last_id)
16915         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
16916                         osp.$mdtosc_proc1.prealloc_next_id)
16917
16918         $LFS df -i
16919
16920         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
16921         #define OBD_FAIL_OST_ENOINO              0x229
16922         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
16923         create_pool $FSNAME.$TESTNAME || return 1
16924         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
16925
16926         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
16927
16928         MDSOBJS=$((last_id - next_id))
16929         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
16930
16931         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
16932         echo "OST still has $count kbytes free"
16933
16934         echo "create $MDSOBJS files @next_id..."
16935         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
16936
16937         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
16938                         osp.$mdtosc_proc1.prealloc_last_id)
16939         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
16940                         osp.$mdtosc_proc1.prealloc_next_id)
16941
16942         echo "after creation, last_id=$last_id2, next_id=$next_id2"
16943         $LFS df -i
16944
16945         echo "cleanup..."
16946
16947         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
16948         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
16949
16950         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
16951                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
16952         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
16953                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
16954         echo "unlink $MDSOBJS files @$next_id..."
16955         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
16956 }
16957 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
16958
16959 test_221() {
16960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16961
16962         dd if=`which date` of=$MOUNT/date oflag=sync
16963         chmod +x $MOUNT/date
16964
16965         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
16966         $LCTL set_param fail_loc=0x80001401
16967
16968         $MOUNT/date > /dev/null
16969         rm -f $MOUNT/date
16970 }
16971 run_test 221 "make sure fault and truncate race to not cause OOM"
16972
16973 test_222a () {
16974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16975
16976         rm -rf $DIR/$tdir
16977         test_mkdir $DIR/$tdir
16978         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16979         createmany -o $DIR/$tdir/$tfile 10
16980         cancel_lru_locks mdc
16981         cancel_lru_locks osc
16982         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
16983         $LCTL set_param fail_loc=0x31a
16984         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
16985         $LCTL set_param fail_loc=0
16986         rm -r $DIR/$tdir
16987 }
16988 run_test 222a "AGL for ls should not trigger CLIO lock failure"
16989
16990 test_222b () {
16991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16992
16993         rm -rf $DIR/$tdir
16994         test_mkdir $DIR/$tdir
16995         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16996         createmany -o $DIR/$tdir/$tfile 10
16997         cancel_lru_locks mdc
16998         cancel_lru_locks osc
16999         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17000         $LCTL set_param fail_loc=0x31a
17001         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17002         $LCTL set_param fail_loc=0
17003 }
17004 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17005
17006 test_223 () {
17007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17008
17009         rm -rf $DIR/$tdir
17010         test_mkdir $DIR/$tdir
17011         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17012         createmany -o $DIR/$tdir/$tfile 10
17013         cancel_lru_locks mdc
17014         cancel_lru_locks osc
17015         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17016         $LCTL set_param fail_loc=0x31b
17017         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17018         $LCTL set_param fail_loc=0
17019         rm -r $DIR/$tdir
17020 }
17021 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17022
17023 test_224a() { # LU-1039, MRP-303
17024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17025
17026         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17027         $LCTL set_param fail_loc=0x508
17028         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17029         $LCTL set_param fail_loc=0
17030         df $DIR
17031 }
17032 run_test 224a "Don't panic on bulk IO failure"
17033
17034 test_224b() { # LU-1039, MRP-303
17035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17036
17037         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17038         cancel_lru_locks osc
17039         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17040         $LCTL set_param fail_loc=0x515
17041         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17042         $LCTL set_param fail_loc=0
17043         df $DIR
17044 }
17045 run_test 224b "Don't panic on bulk IO failure"
17046
17047 test_224c() { # LU-6441
17048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17049         remote_mds_nodsh && skip "remote MDS with nodsh"
17050
17051         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17052         save_writethrough $p
17053         set_cache writethrough on
17054
17055         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17056         local at_max=$($LCTL get_param -n at_max)
17057         local timeout=$($LCTL get_param -n timeout)
17058         local test_at="at_max"
17059         local param_at="$FSNAME.sys.at_max"
17060         local test_timeout="timeout"
17061         local param_timeout="$FSNAME.sys.timeout"
17062
17063         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17064
17065         set_persistent_param_and_check client "$test_at" "$param_at" 0
17066         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17067
17068         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17069         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17070         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17071         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17072         sync
17073         do_facet ost1 "$LCTL set_param fail_loc=0"
17074
17075         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17076         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17077                 $timeout
17078
17079         $LCTL set_param -n $pages_per_rpc
17080         restore_lustre_params < $p
17081         rm -f $p
17082 }
17083 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17084
17085 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17086 test_225a () {
17087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17088         if [ -z ${MDSSURVEY} ]; then
17089                 skip_env "mds-survey not found"
17090         fi
17091         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17092                 skip "Need MDS version at least 2.2.51"
17093
17094         local mds=$(facet_host $SINGLEMDS)
17095         local target=$(do_nodes $mds 'lctl dl' |
17096                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17097
17098         local cmd1="file_count=1000 thrhi=4"
17099         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17100         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17101         local cmd="$cmd1 $cmd2 $cmd3"
17102
17103         rm -f ${TMP}/mds_survey*
17104         echo + $cmd
17105         eval $cmd || error "mds-survey with zero-stripe failed"
17106         cat ${TMP}/mds_survey*
17107         rm -f ${TMP}/mds_survey*
17108 }
17109 run_test 225a "Metadata survey sanity with zero-stripe"
17110
17111 test_225b () {
17112         if [ -z ${MDSSURVEY} ]; then
17113                 skip_env "mds-survey not found"
17114         fi
17115         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17116                 skip "Need MDS version at least 2.2.51"
17117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17118         remote_mds_nodsh && skip "remote MDS with nodsh"
17119         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17120                 skip_env "Need to mount OST to test"
17121         fi
17122
17123         local mds=$(facet_host $SINGLEMDS)
17124         local target=$(do_nodes $mds 'lctl dl' |
17125                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17126
17127         local cmd1="file_count=1000 thrhi=4"
17128         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17129         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17130         local cmd="$cmd1 $cmd2 $cmd3"
17131
17132         rm -f ${TMP}/mds_survey*
17133         echo + $cmd
17134         eval $cmd || error "mds-survey with stripe_count failed"
17135         cat ${TMP}/mds_survey*
17136         rm -f ${TMP}/mds_survey*
17137 }
17138 run_test 225b "Metadata survey sanity with stripe_count = 1"
17139
17140 mcreate_path2fid () {
17141         local mode=$1
17142         local major=$2
17143         local minor=$3
17144         local name=$4
17145         local desc=$5
17146         local path=$DIR/$tdir/$name
17147         local fid
17148         local rc
17149         local fid_path
17150
17151         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17152                 error "cannot create $desc"
17153
17154         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17155         rc=$?
17156         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17157
17158         fid_path=$($LFS fid2path $MOUNT $fid)
17159         rc=$?
17160         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17161
17162         [ "$path" == "$fid_path" ] ||
17163                 error "fid2path returned $fid_path, expected $path"
17164
17165         echo "pass with $path and $fid"
17166 }
17167
17168 test_226a () {
17169         rm -rf $DIR/$tdir
17170         mkdir -p $DIR/$tdir
17171
17172         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17173         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17174         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17175         mcreate_path2fid 0040666 0 0 dir "directory"
17176         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17177         mcreate_path2fid 0100666 0 0 file "regular file"
17178         mcreate_path2fid 0120666 0 0 link "symbolic link"
17179         mcreate_path2fid 0140666 0 0 sock "socket"
17180 }
17181 run_test 226a "call path2fid and fid2path on files of all type"
17182
17183 test_226b () {
17184         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17185
17186         local MDTIDX=1
17187
17188         rm -rf $DIR/$tdir
17189         mkdir -p $DIR/$tdir
17190         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17191                 error "create remote directory failed"
17192         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17193         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17194                                 "character special file (null)"
17195         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17196                                 "character special file (no device)"
17197         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17198         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17199                                 "block special file (loop)"
17200         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17201         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17202         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17203 }
17204 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17205
17206 # LU-1299 Executing or running ldd on a truncated executable does not
17207 # cause an out-of-memory condition.
17208 test_227() {
17209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17210         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17211
17212         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17213         chmod +x $MOUNT/date
17214
17215         $MOUNT/date > /dev/null
17216         ldd $MOUNT/date > /dev/null
17217         rm -f $MOUNT/date
17218 }
17219 run_test 227 "running truncated executable does not cause OOM"
17220
17221 # LU-1512 try to reuse idle OI blocks
17222 test_228a() {
17223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17224         remote_mds_nodsh && skip "remote MDS with nodsh"
17225         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17226
17227         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17228         local myDIR=$DIR/$tdir
17229
17230         mkdir -p $myDIR
17231         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17232         $LCTL set_param fail_loc=0x80001002
17233         createmany -o $myDIR/t- 10000
17234         $LCTL set_param fail_loc=0
17235         # The guard is current the largest FID holder
17236         touch $myDIR/guard
17237         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17238                     tr -d '[')
17239         local IDX=$(($SEQ % 64))
17240
17241         do_facet $SINGLEMDS sync
17242         # Make sure journal flushed.
17243         sleep 6
17244         local blk1=$(do_facet $SINGLEMDS \
17245                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17246                      grep Blockcount | awk '{print $4}')
17247
17248         # Remove old files, some OI blocks will become idle.
17249         unlinkmany $myDIR/t- 10000
17250         # Create new files, idle OI blocks should be reused.
17251         createmany -o $myDIR/t- 2000
17252         do_facet $SINGLEMDS sync
17253         # Make sure journal flushed.
17254         sleep 6
17255         local blk2=$(do_facet $SINGLEMDS \
17256                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17257                      grep Blockcount | awk '{print $4}')
17258
17259         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17260 }
17261 run_test 228a "try to reuse idle OI blocks"
17262
17263 test_228b() {
17264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17265         remote_mds_nodsh && skip "remote MDS with nodsh"
17266         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17267
17268         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17269         local myDIR=$DIR/$tdir
17270
17271         mkdir -p $myDIR
17272         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17273         $LCTL set_param fail_loc=0x80001002
17274         createmany -o $myDIR/t- 10000
17275         $LCTL set_param fail_loc=0
17276         # The guard is current the largest FID holder
17277         touch $myDIR/guard
17278         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17279                     tr -d '[')
17280         local IDX=$(($SEQ % 64))
17281
17282         do_facet $SINGLEMDS sync
17283         # Make sure journal flushed.
17284         sleep 6
17285         local blk1=$(do_facet $SINGLEMDS \
17286                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17287                      grep Blockcount | awk '{print $4}')
17288
17289         # Remove old files, some OI blocks will become idle.
17290         unlinkmany $myDIR/t- 10000
17291
17292         # stop the MDT
17293         stop $SINGLEMDS || error "Fail to stop MDT."
17294         # remount the MDT
17295         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17296
17297         df $MOUNT || error "Fail to df."
17298         # Create new files, idle OI blocks should be reused.
17299         createmany -o $myDIR/t- 2000
17300         do_facet $SINGLEMDS sync
17301         # Make sure journal flushed.
17302         sleep 6
17303         local blk2=$(do_facet $SINGLEMDS \
17304                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17305                      grep Blockcount | awk '{print $4}')
17306
17307         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17308 }
17309 run_test 228b "idle OI blocks can be reused after MDT restart"
17310
17311 #LU-1881
17312 test_228c() {
17313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17314         remote_mds_nodsh && skip "remote MDS with nodsh"
17315         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17316
17317         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17318         local myDIR=$DIR/$tdir
17319
17320         mkdir -p $myDIR
17321         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17322         $LCTL set_param fail_loc=0x80001002
17323         # 20000 files can guarantee there are index nodes in the OI file
17324         createmany -o $myDIR/t- 20000
17325         $LCTL set_param fail_loc=0
17326         # The guard is current the largest FID holder
17327         touch $myDIR/guard
17328         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17329                     tr -d '[')
17330         local IDX=$(($SEQ % 64))
17331
17332         do_facet $SINGLEMDS sync
17333         # Make sure journal flushed.
17334         sleep 6
17335         local blk1=$(do_facet $SINGLEMDS \
17336                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17337                      grep Blockcount | awk '{print $4}')
17338
17339         # Remove old files, some OI blocks will become idle.
17340         unlinkmany $myDIR/t- 20000
17341         rm -f $myDIR/guard
17342         # The OI file should become empty now
17343
17344         # Create new files, idle OI blocks should be reused.
17345         createmany -o $myDIR/t- 2000
17346         do_facet $SINGLEMDS sync
17347         # Make sure journal flushed.
17348         sleep 6
17349         local blk2=$(do_facet $SINGLEMDS \
17350                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17351                      grep Blockcount | awk '{print $4}')
17352
17353         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17354 }
17355 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17356
17357 test_229() { # LU-2482, LU-3448
17358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17359         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17360         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17361                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17362
17363         rm -f $DIR/$tfile
17364
17365         # Create a file with a released layout and stripe count 2.
17366         $MULTIOP $DIR/$tfile H2c ||
17367                 error "failed to create file with released layout"
17368
17369         $LFS getstripe -v $DIR/$tfile
17370
17371         local pattern=$($LFS getstripe -L $DIR/$tfile)
17372         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17373
17374         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17375                 error "getstripe"
17376         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17377         stat $DIR/$tfile || error "failed to stat released file"
17378
17379         chown $RUNAS_ID $DIR/$tfile ||
17380                 error "chown $RUNAS_ID $DIR/$tfile failed"
17381
17382         chgrp $RUNAS_ID $DIR/$tfile ||
17383                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17384
17385         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17386         rm $DIR/$tfile || error "failed to remove released file"
17387 }
17388 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17389
17390 test_230a() {
17391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17392         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17393         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17394                 skip "Need MDS version at least 2.11.52"
17395
17396         local MDTIDX=1
17397
17398         test_mkdir $DIR/$tdir
17399         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17400         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17401         [ $mdt_idx -ne 0 ] &&
17402                 error "create local directory on wrong MDT $mdt_idx"
17403
17404         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17405                         error "create remote directory failed"
17406         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17407         [ $mdt_idx -ne $MDTIDX ] &&
17408                 error "create remote directory on wrong MDT $mdt_idx"
17409
17410         createmany -o $DIR/$tdir/test_230/t- 10 ||
17411                 error "create files on remote directory failed"
17412         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17413         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17414         rm -r $DIR/$tdir || error "unlink remote directory failed"
17415 }
17416 run_test 230a "Create remote directory and files under the remote directory"
17417
17418 test_230b() {
17419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17420         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17421         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17422                 skip "Need MDS version at least 2.11.52"
17423
17424         local MDTIDX=1
17425         local mdt_index
17426         local i
17427         local file
17428         local pid
17429         local stripe_count
17430         local migrate_dir=$DIR/$tdir/migrate_dir
17431         local other_dir=$DIR/$tdir/other_dir
17432
17433         test_mkdir $DIR/$tdir
17434         test_mkdir -i0 -c1 $migrate_dir
17435         test_mkdir -i0 -c1 $other_dir
17436         for ((i=0; i<10; i++)); do
17437                 mkdir -p $migrate_dir/dir_${i}
17438                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17439                         error "create files under remote dir failed $i"
17440         done
17441
17442         cp /etc/passwd $migrate_dir/$tfile
17443         cp /etc/passwd $other_dir/$tfile
17444         chattr +SAD $migrate_dir
17445         chattr +SAD $migrate_dir/$tfile
17446
17447         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17448         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17449         local old_dir_mode=$(stat -c%f $migrate_dir)
17450         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17451
17452         mkdir -p $migrate_dir/dir_default_stripe2
17453         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17454         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17455
17456         mkdir -p $other_dir
17457         ln $migrate_dir/$tfile $other_dir/luna
17458         ln $migrate_dir/$tfile $migrate_dir/sofia
17459         ln $other_dir/$tfile $migrate_dir/david
17460         ln -s $migrate_dir/$tfile $other_dir/zachary
17461         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17462         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17463
17464         local len
17465         local lnktgt
17466
17467         # inline symlink
17468         for len in 58 59 60; do
17469                 lnktgt=$(str_repeat 'l' $len)
17470                 touch $migrate_dir/$lnktgt
17471                 ln -s $lnktgt $migrate_dir/${len}char_ln
17472         done
17473
17474         # PATH_MAX
17475         for len in 4094 4095; do
17476                 lnktgt=$(str_repeat 'l' $len)
17477                 ln -s $lnktgt $migrate_dir/${len}char_ln
17478         done
17479
17480         # NAME_MAX
17481         for len in 254 255; do
17482                 touch $migrate_dir/$(str_repeat 'l' $len)
17483         done
17484
17485         $LFS migrate -m $MDTIDX $migrate_dir ||
17486                 error "fails on migrating remote dir to MDT1"
17487
17488         echo "migratate to MDT1, then checking.."
17489         for ((i = 0; i < 10; i++)); do
17490                 for file in $(find $migrate_dir/dir_${i}); do
17491                         mdt_index=$($LFS getstripe -m $file)
17492                         # broken symlink getstripe will fail
17493                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17494                                 error "$file is not on MDT${MDTIDX}"
17495                 done
17496         done
17497
17498         # the multiple link file should still in MDT0
17499         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17500         [ $mdt_index == 0 ] ||
17501                 error "$file is not on MDT${MDTIDX}"
17502
17503         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17504         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17505                 error " expect $old_dir_flag get $new_dir_flag"
17506
17507         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17508         [ "$old_file_flag" = "$new_file_flag" ] ||
17509                 error " expect $old_file_flag get $new_file_flag"
17510
17511         local new_dir_mode=$(stat -c%f $migrate_dir)
17512         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17513                 error "expect mode $old_dir_mode get $new_dir_mode"
17514
17515         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17516         [ "$old_file_mode" = "$new_file_mode" ] ||
17517                 error "expect mode $old_file_mode get $new_file_mode"
17518
17519         diff /etc/passwd $migrate_dir/$tfile ||
17520                 error "$tfile different after migration"
17521
17522         diff /etc/passwd $other_dir/luna ||
17523                 error "luna different after migration"
17524
17525         diff /etc/passwd $migrate_dir/sofia ||
17526                 error "sofia different after migration"
17527
17528         diff /etc/passwd $migrate_dir/david ||
17529                 error "david different after migration"
17530
17531         diff /etc/passwd $other_dir/zachary ||
17532                 error "zachary different after migration"
17533
17534         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17535                 error "${tfile}_ln different after migration"
17536
17537         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17538                 error "${tfile}_ln_other different after migration"
17539
17540         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
17541         [ $stripe_count = 2 ] ||
17542                 error "dir strpe_count $d != 2 after migration."
17543
17544         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
17545         [ $stripe_count = 2 ] ||
17546                 error "file strpe_count $d != 2 after migration."
17547
17548         #migrate back to MDT0
17549         MDTIDX=0
17550
17551         $LFS migrate -m $MDTIDX $migrate_dir ||
17552                 error "fails on migrating remote dir to MDT0"
17553
17554         echo "migrate back to MDT0, checking.."
17555         for file in $(find $migrate_dir); do
17556                 mdt_index=$($LFS getstripe -m $file)
17557                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17558                         error "$file is not on MDT${MDTIDX}"
17559         done
17560
17561         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17562         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17563                 error " expect $old_dir_flag get $new_dir_flag"
17564
17565         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17566         [ "$old_file_flag" = "$new_file_flag" ] ||
17567                 error " expect $old_file_flag get $new_file_flag"
17568
17569         local new_dir_mode=$(stat -c%f $migrate_dir)
17570         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17571                 error "expect mode $old_dir_mode get $new_dir_mode"
17572
17573         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17574         [ "$old_file_mode" = "$new_file_mode" ] ||
17575                 error "expect mode $old_file_mode get $new_file_mode"
17576
17577         diff /etc/passwd ${migrate_dir}/$tfile ||
17578                 error "$tfile different after migration"
17579
17580         diff /etc/passwd ${other_dir}/luna ||
17581                 error "luna different after migration"
17582
17583         diff /etc/passwd ${migrate_dir}/sofia ||
17584                 error "sofia different after migration"
17585
17586         diff /etc/passwd ${other_dir}/zachary ||
17587                 error "zachary different after migration"
17588
17589         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17590                 error "${tfile}_ln different after migration"
17591
17592         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17593                 error "${tfile}_ln_other different after migration"
17594
17595         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
17596         [ $stripe_count = 2 ] ||
17597                 error "dir strpe_count $d != 2 after migration."
17598
17599         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
17600         [ $stripe_count = 2 ] ||
17601                 error "file strpe_count $d != 2 after migration."
17602
17603         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17604 }
17605 run_test 230b "migrate directory"
17606
17607 test_230c() {
17608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17609         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17610         remote_mds_nodsh && skip "remote MDS with nodsh"
17611         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17612                 skip "Need MDS version at least 2.11.52"
17613
17614         local MDTIDX=1
17615         local total=3
17616         local mdt_index
17617         local file
17618         local migrate_dir=$DIR/$tdir/migrate_dir
17619
17620         #If migrating directory fails in the middle, all entries of
17621         #the directory is still accessiable.
17622         test_mkdir $DIR/$tdir
17623         test_mkdir -i0 -c1 $migrate_dir
17624         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
17625         stat $migrate_dir
17626         createmany -o $migrate_dir/f $total ||
17627                 error "create files under ${migrate_dir} failed"
17628
17629         # fail after migrating top dir, and this will fail only once, so the
17630         # first sub file migration will fail (currently f3), others succeed.
17631         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
17632         do_facet mds1 lctl set_param fail_loc=0x1801
17633         local t=$(ls $migrate_dir | wc -l)
17634         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
17635                 error "migrate should fail"
17636         local u=$(ls $migrate_dir | wc -l)
17637         [ "$u" == "$t" ] || error "$u != $t during migration"
17638
17639         # add new dir/file should succeed
17640         mkdir $migrate_dir/dir ||
17641                 error "mkdir failed under migrating directory"
17642         touch $migrate_dir/file ||
17643                 error "create file failed under migrating directory"
17644
17645         # add file with existing name should fail
17646         for file in $migrate_dir/f*; do
17647                 stat $file > /dev/null || error "stat $file failed"
17648                 $OPENFILE -f O_CREAT:O_EXCL $file &&
17649                         error "open(O_CREAT|O_EXCL) $file should fail"
17650                 $MULTIOP $file m && error "create $file should fail"
17651                 touch $DIR/$tdir/remote_dir/$tfile ||
17652                         error "touch $tfile failed"
17653                 ln $DIR/$tdir/remote_dir/$tfile $file &&
17654                         error "link $file should fail"
17655                 mdt_index=$($LFS getstripe -m $file)
17656                 if [ $mdt_index == 0 ]; then
17657                         # file failed to migrate is not allowed to rename to
17658                         mv $DIR/$tdir/remote_dir/$tfile $file &&
17659                                 error "rename to $file should fail"
17660                 else
17661                         mv $DIR/$tdir/remote_dir/$tfile $file ||
17662                                 error "rename to $file failed"
17663                 fi
17664                 echo hello >> $file || error "write $file failed"
17665         done
17666
17667         # resume migration with different options should fail
17668         $LFS migrate -m 0 $migrate_dir &&
17669                 error "migrate -m 0 $migrate_dir should fail"
17670
17671         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
17672                 error "migrate -c 2 $migrate_dir should fail"
17673
17674         # resume migration should succeed
17675         $LFS migrate -m $MDTIDX $migrate_dir ||
17676                 error "migrate $migrate_dir failed"
17677
17678         echo "Finish migration, then checking.."
17679         for file in $(find $migrate_dir); do
17680                 mdt_index=$($LFS getstripe -m $file)
17681                 [ $mdt_index == $MDTIDX ] ||
17682                         error "$file is not on MDT${MDTIDX}"
17683         done
17684
17685         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17686 }
17687 run_test 230c "check directory accessiblity if migration failed"
17688
17689 test_230d() {
17690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17691         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17692         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17693                 skip "Need MDS version at least 2.11.52"
17694         # LU-11235
17695         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
17696
17697         local migrate_dir=$DIR/$tdir/migrate_dir
17698         local old_index
17699         local new_index
17700         local old_count
17701         local new_count
17702         local new_hash
17703         local mdt_index
17704         local i
17705         local j
17706
17707         old_index=$((RANDOM % MDSCOUNT))
17708         old_count=$((MDSCOUNT - old_index))
17709         new_index=$((RANDOM % MDSCOUNT))
17710         new_count=$((MDSCOUNT - new_index))
17711         new_hash=1 # for all_char
17712
17713         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
17714         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
17715
17716         test_mkdir $DIR/$tdir
17717         test_mkdir -i $old_index -c $old_count $migrate_dir
17718
17719         for ((i=0; i<100; i++)); do
17720                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
17721                 createmany -o $migrate_dir/dir_${i}/f 100 ||
17722                         error "create files under remote dir failed $i"
17723         done
17724
17725         echo -n "Migrate from MDT$old_index "
17726         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
17727         echo -n "to MDT$new_index"
17728         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
17729         echo
17730
17731         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
17732         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
17733                 error "migrate remote dir error"
17734
17735         echo "Finish migration, then checking.."
17736         for file in $(find $migrate_dir); do
17737                 mdt_index=$($LFS getstripe -m $file)
17738                 if [ $mdt_index -lt $new_index ] ||
17739                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
17740                         error "$file is on MDT$mdt_index"
17741                 fi
17742         done
17743
17744         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17745 }
17746 run_test 230d "check migrate big directory"
17747
17748 test_230e() {
17749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17750         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17751         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17752                 skip "Need MDS version at least 2.11.52"
17753
17754         local i
17755         local j
17756         local a_fid
17757         local b_fid
17758
17759         mkdir -p $DIR/$tdir
17760         mkdir $DIR/$tdir/migrate_dir
17761         mkdir $DIR/$tdir/other_dir
17762         touch $DIR/$tdir/migrate_dir/a
17763         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
17764         ls $DIR/$tdir/other_dir
17765
17766         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17767                 error "migrate dir fails"
17768
17769         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17770         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17771
17772         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17773         [ $mdt_index == 0 ] || error "a is not on MDT0"
17774
17775         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
17776                 error "migrate dir fails"
17777
17778         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
17779         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
17780
17781         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17782         [ $mdt_index == 1 ] || error "a is not on MDT1"
17783
17784         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
17785         [ $mdt_index == 1 ] || error "b is not on MDT1"
17786
17787         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17788         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
17789
17790         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
17791
17792         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17793 }
17794 run_test 230e "migrate mulitple local link files"
17795
17796 test_230f() {
17797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17798         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17799         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17800                 skip "Need MDS version at least 2.11.52"
17801
17802         local a_fid
17803         local ln_fid
17804
17805         mkdir -p $DIR/$tdir
17806         mkdir $DIR/$tdir/migrate_dir
17807         $LFS mkdir -i1 $DIR/$tdir/other_dir
17808         touch $DIR/$tdir/migrate_dir/a
17809         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
17810         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
17811         ls $DIR/$tdir/other_dir
17812
17813         # a should be migrated to MDT1, since no other links on MDT0
17814         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17815                 error "#1 migrate dir fails"
17816         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17817         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17818         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17819         [ $mdt_index == 1 ] || error "a is not on MDT1"
17820
17821         # a should stay on MDT1, because it is a mulitple link file
17822         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17823                 error "#2 migrate dir fails"
17824         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17825         [ $mdt_index == 1 ] || error "a is not on MDT1"
17826
17827         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17828                 error "#3 migrate dir fails"
17829
17830         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17831         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
17832         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
17833
17834         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
17835         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
17836
17837         # a should be migrated to MDT0, since no other links on MDT1
17838         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17839                 error "#4 migrate dir fails"
17840         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17841         [ $mdt_index == 0 ] || error "a is not on MDT0"
17842
17843         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17844 }
17845 run_test 230f "migrate mulitple remote link files"
17846
17847 test_230g() {
17848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17849         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17850         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17851                 skip "Need MDS version at least 2.11.52"
17852
17853         mkdir -p $DIR/$tdir/migrate_dir
17854
17855         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
17856                 error "migrating dir to non-exist MDT succeeds"
17857         true
17858 }
17859 run_test 230g "migrate dir to non-exist MDT"
17860
17861 test_230h() {
17862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17863         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17864         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17865                 skip "Need MDS version at least 2.11.52"
17866
17867         local mdt_index
17868
17869         mkdir -p $DIR/$tdir/migrate_dir
17870
17871         $LFS migrate -m1 $DIR &&
17872                 error "migrating mountpoint1 should fail"
17873
17874         $LFS migrate -m1 $DIR/$tdir/.. &&
17875                 error "migrating mountpoint2 should fail"
17876
17877         # same as mv
17878         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
17879                 error "migrating $tdir/migrate_dir/.. should fail"
17880
17881         true
17882 }
17883 run_test 230h "migrate .. and root"
17884
17885 test_230i() {
17886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17887         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17888         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17889                 skip "Need MDS version at least 2.11.52"
17890
17891         mkdir -p $DIR/$tdir/migrate_dir
17892
17893         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
17894                 error "migration fails with a tailing slash"
17895
17896         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
17897                 error "migration fails with two tailing slashes"
17898 }
17899 run_test 230i "lfs migrate -m tolerates trailing slashes"
17900
17901 test_230j() {
17902         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17903         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
17904                 skip "Need MDS version at least 2.11.52"
17905
17906         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
17907         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
17908                 error "create $tfile failed"
17909         cat /etc/passwd > $DIR/$tdir/$tfile
17910
17911         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
17912
17913         cmp /etc/passwd $DIR/$tdir/$tfile ||
17914                 error "DoM file mismatch after migration"
17915 }
17916 run_test 230j "DoM file data not changed after dir migration"
17917
17918 test_230k() {
17919         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
17920         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17921                 skip "Need MDS version at least 2.11.56"
17922
17923         local total=20
17924         local files_on_starting_mdt=0
17925
17926         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
17927         $LFS getdirstripe $DIR/$tdir
17928         for i in $(seq $total); do
17929                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
17930                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
17931                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17932         done
17933
17934         echo "$files_on_starting_mdt files on MDT0"
17935
17936         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
17937         $LFS getdirstripe $DIR/$tdir
17938
17939         files_on_starting_mdt=0
17940         for i in $(seq $total); do
17941                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
17942                         error "file $tfile.$i mismatch after migration"
17943                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
17944                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17945         done
17946
17947         echo "$files_on_starting_mdt files on MDT1 after migration"
17948         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
17949
17950         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
17951         $LFS getdirstripe $DIR/$tdir
17952
17953         files_on_starting_mdt=0
17954         for i in $(seq $total); do
17955                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
17956                         error "file $tfile.$i mismatch after 2nd migration"
17957                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
17958                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17959         done
17960
17961         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
17962         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
17963
17964         true
17965 }
17966 run_test 230k "file data not changed after dir migration"
17967
17968 test_230l() {
17969         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17970         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17971                 skip "Need MDS version at least 2.11.56"
17972
17973         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
17974         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
17975                 error "create files under remote dir failed $i"
17976         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
17977 }
17978 run_test 230l "readdir between MDTs won't crash"
17979
17980 test_230m() {
17981         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17982         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17983                 skip "Need MDS version at least 2.11.56"
17984
17985         local MDTIDX=1
17986         local mig_dir=$DIR/$tdir/migrate_dir
17987         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
17988         local shortstr="b"
17989         local val
17990
17991         echo "Creating files and dirs with xattrs"
17992         test_mkdir $DIR/$tdir
17993         test_mkdir -i0 -c1 $mig_dir
17994         mkdir $mig_dir/dir
17995         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
17996                 error "cannot set xattr attr1 on dir"
17997         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
17998                 error "cannot set xattr attr2 on dir"
17999         touch $mig_dir/dir/f0
18000         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18001                 error "cannot set xattr attr1 on file"
18002         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18003                 error "cannot set xattr attr2 on file"
18004         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18005         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18006         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18007         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18008         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18009         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18010         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18011         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18012         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18013
18014         echo "Migrating to MDT1"
18015         $LFS migrate -m $MDTIDX $mig_dir ||
18016                 error "fails on migrating dir to MDT1"
18017
18018         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18019         echo "Checking xattrs"
18020         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18021         [ "$val" = $longstr ] ||
18022                 error "expecting xattr1 $longstr on dir, found $val"
18023         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18024         [ "$val" = $shortstr ] ||
18025                 error "expecting xattr2 $shortstr on dir, found $val"
18026         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18027         [ "$val" = $longstr ] ||
18028                 error "expecting xattr1 $longstr on file, found $val"
18029         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18030         [ "$val" = $shortstr ] ||
18031                 error "expecting xattr2 $shortstr on file, found $val"
18032 }
18033 run_test 230m "xattrs not changed after dir migration"
18034
18035 test_230n() {
18036         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18037         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18038                 skip "Need MDS version at least 2.13.53"
18039
18040         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18041         cat /etc/hosts > $DIR/$tdir/$tfile
18042         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18043         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18044
18045         cmp /etc/hosts $DIR/$tdir/$tfile ||
18046                 error "File data mismatch after migration"
18047 }
18048 run_test 230n "Dir migration with mirrored file"
18049
18050 test_230o() {
18051         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18052         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18053                 skip "Need MDS version at least 2.13.52"
18054
18055         local mdts=$(comma_list $(mdts_nodes))
18056         local timeout=100
18057
18058         local restripe_status
18059         local delta
18060         local i
18061         local j
18062
18063         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18064
18065         # in case "crush" hash type is not set
18066         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18067
18068         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18069                            mdt.*MDT0000.enable_dir_restripe)
18070         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18071         stack_trap "do_nodes $mdts $LCTL set_param \
18072                     mdt.*.enable_dir_restripe=$restripe_status"
18073
18074         mkdir $DIR/$tdir
18075         createmany -m $DIR/$tdir/f 100 ||
18076                 error "create files under remote dir failed $i"
18077         createmany -d $DIR/$tdir/d 100 ||
18078                 error "create dirs under remote dir failed $i"
18079
18080         for i in $(seq 2 $MDSCOUNT); do
18081                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18082                 $LFS setdirstripe -c $i $DIR/$tdir ||
18083                         error "split -c $i $tdir failed"
18084                 wait_update $HOSTNAME \
18085                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18086                         error "dir split not finished"
18087                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18088                         awk '/migrate/ {sum += $2} END { print sum }')
18089                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18090                 # delta is around total_files/stripe_count
18091                 [ $delta -lt $((200 /(i - 1))) ] ||
18092                         error "$delta files migrated"
18093         done
18094 }
18095 run_test 230o "dir split"
18096
18097 test_230p() {
18098         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18099         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18100                 skip "Need MDS version at least 2.13.52"
18101
18102         local mdts=$(comma_list $(mdts_nodes))
18103         local timeout=100
18104
18105         local restripe_status
18106         local delta
18107         local i
18108         local j
18109
18110         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18111
18112         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18113
18114         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18115                            mdt.*MDT0000.enable_dir_restripe)
18116         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18117         stack_trap "do_nodes $mdts $LCTL set_param \
18118                     mdt.*.enable_dir_restripe=$restripe_status"
18119
18120         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18121         createmany -m $DIR/$tdir/f 100 ||
18122                 error "create files under remote dir failed $i"
18123         createmany -d $DIR/$tdir/d 100 ||
18124                 error "create dirs under remote dir failed $i"
18125
18126         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18127                 local mdt_hash="crush"
18128
18129                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18130                 $LFS setdirstripe -c $i $DIR/$tdir ||
18131                         error "split -c $i $tdir failed"
18132                 [ $i -eq 1 ] && mdt_hash="none"
18133                 wait_update $HOSTNAME \
18134                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18135                         error "dir merge not finished"
18136                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18137                         awk '/migrate/ {sum += $2} END { print sum }')
18138                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18139                 # delta is around total_files/stripe_count
18140                 [ $delta -lt $((200 / i)) ] ||
18141                         error "$delta files migrated"
18142         done
18143 }
18144 run_test 230p "dir merge"
18145
18146 test_230q() {
18147         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18148         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18149                 skip "Need MDS version at least 2.13.52"
18150
18151         local mdts=$(comma_list $(mdts_nodes))
18152         local saved_threshold=$(do_facet mds1 \
18153                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18154         local saved_delta=$(do_facet mds1 \
18155                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18156         local threshold=100
18157         local delta=2
18158         local total=0
18159         local stripe_count=0
18160         local stripe_index
18161         local nr_files
18162
18163         stack_trap "do_nodes $mdts $LCTL set_param \
18164                     mdt.*.dir_split_count=$saved_threshold"
18165         stack_trap "do_nodes $mdts $LCTL set_param \
18166                     mdt.*.dir_split_delta=$saved_delta"
18167         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18168         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18169         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18170         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18171         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18172         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18173
18174         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18175         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18176
18177         while [ $stripe_count -lt $MDSCOUNT ]; do
18178                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18179                         error "create sub files failed"
18180                 stat $DIR/$tdir > /dev/null
18181                 total=$((total + threshold * 3 / 2))
18182                 stripe_count=$((stripe_count + delta))
18183                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18184
18185                 wait_update $HOSTNAME \
18186                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18187                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18188
18189                 wait_update $HOSTNAME \
18190                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18191                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18192
18193                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18194                            grep -w $stripe_index | wc -l)
18195                 echo "$nr_files files on MDT$stripe_index after split"
18196                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18197                         error "$nr_files files on MDT$stripe_index after split"
18198
18199                 nr_files=$(ls $DIR/$tdir | wc -w)
18200                 [ $nr_files -eq $total ] ||
18201                         error "total sub files $nr_files != $total"
18202         done
18203 }
18204 run_test 230q "dir auto split"
18205
18206 test_231a()
18207 {
18208         # For simplicity this test assumes that max_pages_per_rpc
18209         # is the same across all OSCs
18210         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18211         local bulk_size=$((max_pages * PAGE_SIZE))
18212         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18213                                        head -n 1)
18214
18215         mkdir -p $DIR/$tdir
18216         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18217                 error "failed to set stripe with -S ${brw_size}M option"
18218
18219         # clear the OSC stats
18220         $LCTL set_param osc.*.stats=0 &>/dev/null
18221         stop_writeback
18222
18223         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18224         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18225                 oflag=direct &>/dev/null || error "dd failed"
18226
18227         sync; sleep 1; sync # just to be safe
18228         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18229         if [ x$nrpcs != "x1" ]; then
18230                 $LCTL get_param osc.*.stats
18231                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18232         fi
18233
18234         start_writeback
18235         # Drop the OSC cache, otherwise we will read from it
18236         cancel_lru_locks osc
18237
18238         # clear the OSC stats
18239         $LCTL set_param osc.*.stats=0 &>/dev/null
18240
18241         # Client reads $bulk_size.
18242         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18243                 iflag=direct &>/dev/null || error "dd failed"
18244
18245         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18246         if [ x$nrpcs != "x1" ]; then
18247                 $LCTL get_param osc.*.stats
18248                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18249         fi
18250 }
18251 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18252
18253 test_231b() {
18254         mkdir -p $DIR/$tdir
18255         local i
18256         for i in {0..1023}; do
18257                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18258                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18259                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18260         done
18261         sync
18262 }
18263 run_test 231b "must not assert on fully utilized OST request buffer"
18264
18265 test_232a() {
18266         mkdir -p $DIR/$tdir
18267         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18268
18269         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18270         do_facet ost1 $LCTL set_param fail_loc=0x31c
18271
18272         # ignore dd failure
18273         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
18274
18275         do_facet ost1 $LCTL set_param fail_loc=0
18276         umount_client $MOUNT || error "umount failed"
18277         mount_client $MOUNT || error "mount failed"
18278         stop ost1 || error "cannot stop ost1"
18279         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18280 }
18281 run_test 232a "failed lock should not block umount"
18282
18283 test_232b() {
18284         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
18285                 skip "Need MDS version at least 2.10.58"
18286
18287         mkdir -p $DIR/$tdir
18288         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18289         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
18290         sync
18291         cancel_lru_locks osc
18292
18293         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18294         do_facet ost1 $LCTL set_param fail_loc=0x31c
18295
18296         # ignore failure
18297         $LFS data_version $DIR/$tdir/$tfile || true
18298
18299         do_facet ost1 $LCTL set_param fail_loc=0
18300         umount_client $MOUNT || error "umount failed"
18301         mount_client $MOUNT || error "mount failed"
18302         stop ost1 || error "cannot stop ost1"
18303         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18304 }
18305 run_test 232b "failed data version lock should not block umount"
18306
18307 test_233a() {
18308         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
18309                 skip "Need MDS version at least 2.3.64"
18310         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18311
18312         local fid=$($LFS path2fid $MOUNT)
18313
18314         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18315                 error "cannot access $MOUNT using its FID '$fid'"
18316 }
18317 run_test 233a "checking that OBF of the FS root succeeds"
18318
18319 test_233b() {
18320         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
18321                 skip "Need MDS version at least 2.5.90"
18322         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18323
18324         local fid=$($LFS path2fid $MOUNT/.lustre)
18325
18326         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18327                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
18328
18329         fid=$($LFS path2fid $MOUNT/.lustre/fid)
18330         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18331                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
18332 }
18333 run_test 233b "checking that OBF of the FS .lustre succeeds"
18334
18335 test_234() {
18336         local p="$TMP/sanityN-$TESTNAME.parameters"
18337         save_lustre_params client "llite.*.xattr_cache" > $p
18338         lctl set_param llite.*.xattr_cache 1 ||
18339                 skip_env "xattr cache is not supported"
18340
18341         mkdir -p $DIR/$tdir || error "mkdir failed"
18342         touch $DIR/$tdir/$tfile || error "touch failed"
18343         # OBD_FAIL_LLITE_XATTR_ENOMEM
18344         $LCTL set_param fail_loc=0x1405
18345         getfattr -n user.attr $DIR/$tdir/$tfile &&
18346                 error "getfattr should have failed with ENOMEM"
18347         $LCTL set_param fail_loc=0x0
18348         rm -rf $DIR/$tdir
18349
18350         restore_lustre_params < $p
18351         rm -f $p
18352 }
18353 run_test 234 "xattr cache should not crash on ENOMEM"
18354
18355 test_235() {
18356         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
18357                 skip "Need MDS version at least 2.4.52"
18358
18359         flock_deadlock $DIR/$tfile
18360         local RC=$?
18361         case $RC in
18362                 0)
18363                 ;;
18364                 124) error "process hangs on a deadlock"
18365                 ;;
18366                 *) error "error executing flock_deadlock $DIR/$tfile"
18367                 ;;
18368         esac
18369 }
18370 run_test 235 "LU-1715: flock deadlock detection does not work properly"
18371
18372 #LU-2935
18373 test_236() {
18374         check_swap_layouts_support
18375
18376         local ref1=/etc/passwd
18377         local ref2=/etc/group
18378         local file1=$DIR/$tdir/f1
18379         local file2=$DIR/$tdir/f2
18380
18381         test_mkdir -c1 $DIR/$tdir
18382         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
18383         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
18384         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
18385         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
18386         local fd=$(free_fd)
18387         local cmd="exec $fd<>$file2"
18388         eval $cmd
18389         rm $file2
18390         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
18391                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
18392         cmd="exec $fd>&-"
18393         eval $cmd
18394         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18395
18396         #cleanup
18397         rm -rf $DIR/$tdir
18398 }
18399 run_test 236 "Layout swap on open unlinked file"
18400
18401 # LU-4659 linkea consistency
18402 test_238() {
18403         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18404                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18405                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18406                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18407
18408         touch $DIR/$tfile
18409         ln $DIR/$tfile $DIR/$tfile.lnk
18410         touch $DIR/$tfile.new
18411         mv $DIR/$tfile.new $DIR/$tfile
18412         local fid1=$($LFS path2fid $DIR/$tfile)
18413         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
18414         local path1=$($LFS fid2path $FSNAME "$fid1")
18415         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
18416         local path2=$($LFS fid2path $FSNAME "$fid2")
18417         [ $tfile.lnk == $path2 ] ||
18418                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
18419         rm -f $DIR/$tfile*
18420 }
18421 run_test 238 "Verify linkea consistency"
18422
18423 test_239A() { # was test_239
18424         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
18425                 skip "Need MDS version at least 2.5.60"
18426
18427         local list=$(comma_list $(mdts_nodes))
18428
18429         mkdir -p $DIR/$tdir
18430         createmany -o $DIR/$tdir/f- 5000
18431         unlinkmany $DIR/$tdir/f- 5000
18432         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
18433                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
18434         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
18435                         osp.*MDT*.sync_in_flight" | calc_sum)
18436         [ "$changes" -eq 0 ] || error "$changes not synced"
18437 }
18438 run_test 239A "osp_sync test"
18439
18440 test_239a() { #LU-5297
18441         remote_mds_nodsh && skip "remote MDS with nodsh"
18442
18443         touch $DIR/$tfile
18444         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
18445         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
18446         chgrp $RUNAS_GID $DIR/$tfile
18447         wait_delete_completed
18448 }
18449 run_test 239a "process invalid osp sync record correctly"
18450
18451 test_239b() { #LU-5297
18452         remote_mds_nodsh && skip "remote MDS with nodsh"
18453
18454         touch $DIR/$tfile1
18455         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
18456         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
18457         chgrp $RUNAS_GID $DIR/$tfile1
18458         wait_delete_completed
18459         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18460         touch $DIR/$tfile2
18461         chgrp $RUNAS_GID $DIR/$tfile2
18462         wait_delete_completed
18463 }
18464 run_test 239b "process osp sync record with ENOMEM error correctly"
18465
18466 test_240() {
18467         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18468         remote_mds_nodsh && skip "remote MDS with nodsh"
18469
18470         mkdir -p $DIR/$tdir
18471
18472         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
18473                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
18474         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
18475                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
18476
18477         umount_client $MOUNT || error "umount failed"
18478         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
18479         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
18480         mount_client $MOUNT || error "failed to mount client"
18481
18482         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
18483         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
18484 }
18485 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
18486
18487 test_241_bio() {
18488         local count=$1
18489         local bsize=$2
18490
18491         for LOOP in $(seq $count); do
18492                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
18493                 cancel_lru_locks $OSC || true
18494         done
18495 }
18496
18497 test_241_dio() {
18498         local count=$1
18499         local bsize=$2
18500
18501         for LOOP in $(seq $1); do
18502                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
18503                         2>/dev/null
18504         done
18505 }
18506
18507 test_241a() { # was test_241
18508         local bsize=$PAGE_SIZE
18509
18510         (( bsize < 40960 )) && bsize=40960
18511         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18512         ls -la $DIR/$tfile
18513         cancel_lru_locks $OSC
18514         test_241_bio 1000 $bsize &
18515         PID=$!
18516         test_241_dio 1000 $bsize
18517         wait $PID
18518 }
18519 run_test 241a "bio vs dio"
18520
18521 test_241b() {
18522         local bsize=$PAGE_SIZE
18523
18524         (( bsize < 40960 )) && bsize=40960
18525         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18526         ls -la $DIR/$tfile
18527         test_241_dio 1000 $bsize &
18528         PID=$!
18529         test_241_dio 1000 $bsize
18530         wait $PID
18531 }
18532 run_test 241b "dio vs dio"
18533
18534 test_242() {
18535         remote_mds_nodsh && skip "remote MDS with nodsh"
18536
18537         mkdir -p $DIR/$tdir
18538         touch $DIR/$tdir/$tfile
18539
18540         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
18541         do_facet mds1 lctl set_param fail_loc=0x105
18542         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
18543
18544         do_facet mds1 lctl set_param fail_loc=0
18545         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
18546 }
18547 run_test 242 "mdt_readpage failure should not cause directory unreadable"
18548
18549 test_243()
18550 {
18551         test_mkdir $DIR/$tdir
18552         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
18553 }
18554 run_test 243 "various group lock tests"
18555
18556 test_244a()
18557 {
18558         test_mkdir $DIR/$tdir
18559         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
18560         sendfile_grouplock $DIR/$tdir/$tfile || \
18561                 error "sendfile+grouplock failed"
18562         rm -rf $DIR/$tdir
18563 }
18564 run_test 244a "sendfile with group lock tests"
18565
18566 test_244b()
18567 {
18568         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18569
18570         local threads=50
18571         local size=$((1024*1024))
18572
18573         test_mkdir $DIR/$tdir
18574         for i in $(seq 1 $threads); do
18575                 local file=$DIR/$tdir/file_$((i / 10))
18576                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
18577                 local pids[$i]=$!
18578         done
18579         for i in $(seq 1 $threads); do
18580                 wait ${pids[$i]}
18581         done
18582 }
18583 run_test 244b "multi-threaded write with group lock"
18584
18585 test_245() {
18586         local flagname="multi_mod_rpcs"
18587         local connect_data_name="max_mod_rpcs"
18588         local out
18589
18590         # check if multiple modify RPCs flag is set
18591         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
18592                 grep "connect_flags:")
18593         echo "$out"
18594
18595         echo "$out" | grep -qw $flagname
18596         if [ $? -ne 0 ]; then
18597                 echo "connect flag $flagname is not set"
18598                 return
18599         fi
18600
18601         # check if multiple modify RPCs data is set
18602         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
18603         echo "$out"
18604
18605         echo "$out" | grep -qw $connect_data_name ||
18606                 error "import should have connect data $connect_data_name"
18607 }
18608 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
18609
18610 cleanup_247() {
18611         local submount=$1
18612
18613         trap 0
18614         umount_client $submount
18615         rmdir $submount
18616 }
18617
18618 test_247a() {
18619         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18620                 grep -q subtree ||
18621                 skip_env "Fileset feature is not supported"
18622
18623         local submount=${MOUNT}_$tdir
18624
18625         mkdir $MOUNT/$tdir
18626         mkdir -p $submount || error "mkdir $submount failed"
18627         FILESET="$FILESET/$tdir" mount_client $submount ||
18628                 error "mount $submount failed"
18629         trap "cleanup_247 $submount" EXIT
18630         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
18631         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
18632                 error "read $MOUNT/$tdir/$tfile failed"
18633         cleanup_247 $submount
18634 }
18635 run_test 247a "mount subdir as fileset"
18636
18637 test_247b() {
18638         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18639                 skip_env "Fileset feature is not supported"
18640
18641         local submount=${MOUNT}_$tdir
18642
18643         rm -rf $MOUNT/$tdir
18644         mkdir -p $submount || error "mkdir $submount failed"
18645         SKIP_FILESET=1
18646         FILESET="$FILESET/$tdir" mount_client $submount &&
18647                 error "mount $submount should fail"
18648         rmdir $submount
18649 }
18650 run_test 247b "mount subdir that dose not exist"
18651
18652 test_247c() {
18653         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18654                 skip_env "Fileset feature is not supported"
18655
18656         local submount=${MOUNT}_$tdir
18657
18658         mkdir -p $MOUNT/$tdir/dir1
18659         mkdir -p $submount || error "mkdir $submount failed"
18660         trap "cleanup_247 $submount" EXIT
18661         FILESET="$FILESET/$tdir" mount_client $submount ||
18662                 error "mount $submount failed"
18663         local fid=$($LFS path2fid $MOUNT/)
18664         $LFS fid2path $submount $fid && error "fid2path should fail"
18665         cleanup_247 $submount
18666 }
18667 run_test 247c "running fid2path outside subdirectory root"
18668
18669 test_247d() {
18670         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18671                 skip "Fileset feature is not supported"
18672
18673         local submount=${MOUNT}_$tdir
18674
18675         mkdir -p $MOUNT/$tdir/dir1
18676         mkdir -p $submount || error "mkdir $submount failed"
18677         FILESET="$FILESET/$tdir" mount_client $submount ||
18678                 error "mount $submount failed"
18679         trap "cleanup_247 $submount" EXIT
18680
18681         local td=$submount/dir1
18682         local fid=$($LFS path2fid $td)
18683         [ -z "$fid" ] && error "path2fid unable to get $td FID"
18684
18685         # check that we get the same pathname back
18686         local rootpath
18687         local found
18688         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
18689                 echo "$rootpath $fid"
18690                 found=$($LFS fid2path $rootpath "$fid")
18691                 [ -n "found" ] || error "fid2path should succeed"
18692                 [ "$found" == "$td" ] || error "fid2path $found != $td"
18693         done
18694         # check wrong root path format
18695         rootpath=$submount"_wrong"
18696         found=$($LFS fid2path $rootpath "$fid")
18697         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
18698
18699         cleanup_247 $submount
18700 }
18701 run_test 247d "running fid2path inside subdirectory root"
18702
18703 # LU-8037
18704 test_247e() {
18705         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18706                 grep -q subtree ||
18707                 skip "Fileset feature is not supported"
18708
18709         local submount=${MOUNT}_$tdir
18710
18711         mkdir $MOUNT/$tdir
18712         mkdir -p $submount || error "mkdir $submount failed"
18713         FILESET="$FILESET/.." mount_client $submount &&
18714                 error "mount $submount should fail"
18715         rmdir $submount
18716 }
18717 run_test 247e "mount .. as fileset"
18718
18719 test_247f() {
18720         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18721         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18722                 skip "Need at least version 2.13.52"
18723         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18724                 grep -q subtree ||
18725                 skip "Fileset feature is not supported"
18726
18727         mkdir $DIR/$tdir || error "mkdir $tdir failed"
18728         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
18729                 error "mkdir remote failed"
18730         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
18731         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
18732                 error "mkdir striped failed"
18733         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
18734
18735         local submount=${MOUNT}_$tdir
18736
18737         mkdir -p $submount || error "mkdir $submount failed"
18738
18739         local dir
18740         local fileset=$FILESET
18741
18742         for dir in $tdir/remote $tdir/remote/subdir \
18743                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
18744                 FILESET="$fileset/$dir" mount_client $submount ||
18745                         error "mount $dir failed"
18746                 umount_client $submount
18747         done
18748 }
18749 run_test 247f "mount striped or remote directory as fileset"
18750
18751 test_248a() {
18752         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
18753         [ -z "$fast_read_sav" ] && skip "no fast read support"
18754
18755         # create a large file for fast read verification
18756         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
18757
18758         # make sure the file is created correctly
18759         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
18760                 { rm -f $DIR/$tfile; skip "file creation error"; }
18761
18762         echo "Test 1: verify that fast read is 4 times faster on cache read"
18763
18764         # small read with fast read enabled
18765         $LCTL set_param -n llite.*.fast_read=1
18766         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18767                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18768                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18769         # small read with fast read disabled
18770         $LCTL set_param -n llite.*.fast_read=0
18771         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18772                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18773                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18774
18775         # verify that fast read is 4 times faster for cache read
18776         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
18777                 error_not_in_vm "fast read was not 4 times faster: " \
18778                            "$t_fast vs $t_slow"
18779
18780         echo "Test 2: verify the performance between big and small read"
18781         $LCTL set_param -n llite.*.fast_read=1
18782
18783         # 1k non-cache read
18784         cancel_lru_locks osc
18785         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
18786                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18787                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18788
18789         # 1M non-cache read
18790         cancel_lru_locks osc
18791         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
18792                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18793                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18794
18795         # verify that big IO is not 4 times faster than small IO
18796         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
18797                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
18798
18799         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
18800         rm -f $DIR/$tfile
18801 }
18802 run_test 248a "fast read verification"
18803
18804 test_248b() {
18805         # Default short_io_bytes=16384, try both smaller and larger sizes.
18806         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
18807         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
18808         echo "bs=53248 count=113 normal buffered write"
18809         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
18810                 error "dd of initial data file failed"
18811         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
18812
18813         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
18814         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
18815                 error "dd with sync normal writes failed"
18816         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
18817
18818         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
18819         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
18820                 error "dd with sync small writes failed"
18821         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
18822
18823         cancel_lru_locks osc
18824
18825         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
18826         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
18827         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
18828         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
18829                 iflag=direct || error "dd with O_DIRECT small read failed"
18830         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
18831         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
18832                 error "compare $TMP/$tfile.1 failed"
18833
18834         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
18835         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
18836
18837         # just to see what the maximum tunable value is, and test parsing
18838         echo "test invalid parameter 2MB"
18839         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
18840                 error "too-large short_io_bytes allowed"
18841         echo "test maximum parameter 512KB"
18842         # if we can set a larger short_io_bytes, run test regardless of version
18843         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
18844                 # older clients may not allow setting it this large, that's OK
18845                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
18846                         skip "Need at least client version 2.13.50"
18847                 error "medium short_io_bytes failed"
18848         fi
18849         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
18850         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
18851
18852         echo "test large parameter 64KB"
18853         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
18854         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
18855
18856         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
18857         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
18858                 error "dd with sync large writes failed"
18859         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
18860
18861         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
18862         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
18863         num=$((113 * 4096 / PAGE_SIZE))
18864         echo "bs=$size count=$num oflag=direct large write $tfile.3"
18865         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
18866                 error "dd with O_DIRECT large writes failed"
18867         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
18868                 error "compare $DIR/$tfile.3 failed"
18869
18870         cancel_lru_locks osc
18871
18872         echo "bs=$size count=$num iflag=direct large read $tfile.2"
18873         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
18874                 error "dd with O_DIRECT large read failed"
18875         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
18876                 error "compare $TMP/$tfile.2 failed"
18877
18878         echo "bs=$size count=$num iflag=direct large read $tfile.3"
18879         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
18880                 error "dd with O_DIRECT large read failed"
18881         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
18882                 error "compare $TMP/$tfile.3 failed"
18883 }
18884 run_test 248b "test short_io read and write for both small and large sizes"
18885
18886 test_249() { # LU-7890
18887         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
18888                 skip "Need at least version 2.8.54"
18889
18890         rm -f $DIR/$tfile
18891         $LFS setstripe -c 1 $DIR/$tfile
18892         # Offset 2T == 4k * 512M
18893         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
18894                 error "dd to 2T offset failed"
18895 }
18896 run_test 249 "Write above 2T file size"
18897
18898 test_250() {
18899         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
18900          && skip "no 16TB file size limit on ZFS"
18901
18902         $LFS setstripe -c 1 $DIR/$tfile
18903         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
18904         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
18905         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
18906         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
18907                 conv=notrunc,fsync && error "append succeeded"
18908         return 0
18909 }
18910 run_test 250 "Write above 16T limit"
18911
18912 test_251() {
18913         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
18914
18915         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
18916         #Skip once - writing the first stripe will succeed
18917         $LCTL set_param fail_loc=0xa0001407 fail_val=1
18918         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
18919                 error "short write happened"
18920
18921         $LCTL set_param fail_loc=0xa0001407 fail_val=1
18922         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
18923                 error "short read happened"
18924
18925         rm -f $DIR/$tfile
18926 }
18927 run_test 251 "Handling short read and write correctly"
18928
18929 test_252() {
18930         remote_mds_nodsh && skip "remote MDS with nodsh"
18931         remote_ost_nodsh && skip "remote OST with nodsh"
18932         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
18933                 skip_env "ldiskfs only test"
18934         fi
18935
18936         local tgt
18937         local dev
18938         local out
18939         local uuid
18940         local num
18941         local gen
18942
18943         # check lr_reader on OST0000
18944         tgt=ost1
18945         dev=$(facet_device $tgt)
18946         out=$(do_facet $tgt $LR_READER $dev)
18947         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
18948         echo "$out"
18949         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
18950         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
18951                 error "Invalid uuid returned by $LR_READER on target $tgt"
18952         echo -e "uuid returned by $LR_READER is '$uuid'\n"
18953
18954         # check lr_reader -c on MDT0000
18955         tgt=mds1
18956         dev=$(facet_device $tgt)
18957         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
18958                 skip "$LR_READER does not support additional options"
18959         fi
18960         out=$(do_facet $tgt $LR_READER -c $dev)
18961         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
18962         echo "$out"
18963         num=$(echo "$out" | grep -c "mdtlov")
18964         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
18965                 error "Invalid number of mdtlov clients returned by $LR_READER"
18966         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
18967
18968         # check lr_reader -cr on MDT0000
18969         out=$(do_facet $tgt $LR_READER -cr $dev)
18970         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
18971         echo "$out"
18972         echo "$out" | grep -q "^reply_data:$" ||
18973                 error "$LR_READER should have returned 'reply_data' section"
18974         num=$(echo "$out" | grep -c "client_generation")
18975         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
18976 }
18977 run_test 252 "check lr_reader tool"
18978
18979 test_253() {
18980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18981         remote_mds_nodsh && skip "remote MDS with nodsh"
18982         remote_mgs_nodsh && skip "remote MGS with nodsh"
18983
18984         local ostidx=0
18985         local rc=0
18986         local ost_name=$(ostname_from_index $ostidx)
18987
18988         # on the mdt's osc
18989         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
18990         do_facet $SINGLEMDS $LCTL get_param -n \
18991                 osp.$mdtosc_proc1.reserved_mb_high ||
18992                 skip  "remote MDS does not support reserved_mb_high"
18993
18994         rm -rf $DIR/$tdir
18995         wait_mds_ost_sync
18996         wait_delete_completed
18997         mkdir $DIR/$tdir
18998
18999         pool_add $TESTNAME || error "Pool creation failed"
19000         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19001
19002         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19003                 error "Setstripe failed"
19004
19005         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19006
19007         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19008                     grep "watermarks")
19009         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19010
19011         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19012                         osp.$mdtosc_proc1.prealloc_status)
19013         echo "prealloc_status $oa_status"
19014
19015         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19016                 error "File creation should fail"
19017
19018         #object allocation was stopped, but we still able to append files
19019         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19020                 oflag=append || error "Append failed"
19021
19022         rm -f $DIR/$tdir/$tfile.0
19023
19024         # For this test, we want to delete the files we created to go out of
19025         # space but leave the watermark, so we remain nearly out of space
19026         ost_watermarks_enospc_delete_files $tfile $ostidx
19027
19028         wait_delete_completed
19029
19030         sleep_maxage
19031
19032         for i in $(seq 10 12); do
19033                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19034                         2>/dev/null || error "File creation failed after rm"
19035         done
19036
19037         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19038                         osp.$mdtosc_proc1.prealloc_status)
19039         echo "prealloc_status $oa_status"
19040
19041         if (( oa_status != 0 )); then
19042                 error "Object allocation still disable after rm"
19043         fi
19044 }
19045 run_test 253 "Check object allocation limit"
19046
19047 test_254() {
19048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19049         remote_mds_nodsh && skip "remote MDS with nodsh"
19050         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19051                 skip "MDS does not support changelog_size"
19052
19053         local cl_user
19054         local MDT0=$(facet_svc $SINGLEMDS)
19055
19056         changelog_register || error "changelog_register failed"
19057
19058         changelog_clear 0 || error "changelog_clear failed"
19059
19060         local size1=$(do_facet $SINGLEMDS \
19061                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19062         echo "Changelog size $size1"
19063
19064         rm -rf $DIR/$tdir
19065         $LFS mkdir -i 0 $DIR/$tdir
19066         # change something
19067         mkdir -p $DIR/$tdir/pics/2008/zachy
19068         touch $DIR/$tdir/pics/2008/zachy/timestamp
19069         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19070         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19071         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19072         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19073         rm $DIR/$tdir/pics/desktop.jpg
19074
19075         local size2=$(do_facet $SINGLEMDS \
19076                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19077         echo "Changelog size after work $size2"
19078
19079         (( $size2 > $size1 )) ||
19080                 error "new Changelog size=$size2 less than old size=$size1"
19081 }
19082 run_test 254 "Check changelog size"
19083
19084 ladvise_no_type()
19085 {
19086         local type=$1
19087         local file=$2
19088
19089         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19090                 awk -F: '{print $2}' | grep $type > /dev/null
19091         if [ $? -ne 0 ]; then
19092                 return 0
19093         fi
19094         return 1
19095 }
19096
19097 ladvise_no_ioctl()
19098 {
19099         local file=$1
19100
19101         lfs ladvise -a willread $file > /dev/null 2>&1
19102         if [ $? -eq 0 ]; then
19103                 return 1
19104         fi
19105
19106         lfs ladvise -a willread $file 2>&1 |
19107                 grep "Inappropriate ioctl for device" > /dev/null
19108         if [ $? -eq 0 ]; then
19109                 return 0
19110         fi
19111         return 1
19112 }
19113
19114 percent() {
19115         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19116 }
19117
19118 # run a random read IO workload
19119 # usage: random_read_iops <filename> <filesize> <iosize>
19120 random_read_iops() {
19121         local file=$1
19122         local fsize=$2
19123         local iosize=${3:-4096}
19124
19125         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19126                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19127 }
19128
19129 drop_file_oss_cache() {
19130         local file="$1"
19131         local nodes="$2"
19132
19133         $LFS ladvise -a dontneed $file 2>/dev/null ||
19134                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19135 }
19136
19137 ladvise_willread_performance()
19138 {
19139         local repeat=10
19140         local average_origin=0
19141         local average_cache=0
19142         local average_ladvise=0
19143
19144         for ((i = 1; i <= $repeat; i++)); do
19145                 echo "Iter $i/$repeat: reading without willread hint"
19146                 cancel_lru_locks osc
19147                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19148                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19149                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19150                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19151
19152                 cancel_lru_locks osc
19153                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19154                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19155                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19156
19157                 cancel_lru_locks osc
19158                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19159                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19160                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19161                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19162                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19163         done
19164         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19165         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19166         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19167
19168         speedup_cache=$(percent $average_cache $average_origin)
19169         speedup_ladvise=$(percent $average_ladvise $average_origin)
19170
19171         echo "Average uncached read: $average_origin"
19172         echo "Average speedup with OSS cached read: " \
19173                 "$average_cache = +$speedup_cache%"
19174         echo "Average speedup with ladvise willread: " \
19175                 "$average_ladvise = +$speedup_ladvise%"
19176
19177         local lowest_speedup=20
19178         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19179                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19180                         "got $average_cache%. Skipping ladvise willread check."
19181                 return 0
19182         fi
19183
19184         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19185         # it is still good to run until then to exercise 'ladvise willread'
19186         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19187                 [ "$ost1_FSTYPE" = "zfs" ] &&
19188                 echo "osd-zfs does not support dontneed or drop_caches" &&
19189                 return 0
19190
19191         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19192         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
19193                 error_not_in_vm "Speedup with willread is less than " \
19194                         "$lowest_speedup%, got $average_ladvise%"
19195 }
19196
19197 test_255a() {
19198         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19199                 skip "lustre < 2.8.54 does not support ladvise "
19200         remote_ost_nodsh && skip "remote OST with nodsh"
19201
19202         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19203
19204         ladvise_no_type willread $DIR/$tfile &&
19205                 skip "willread ladvise is not supported"
19206
19207         ladvise_no_ioctl $DIR/$tfile &&
19208                 skip "ladvise ioctl is not supported"
19209
19210         local size_mb=100
19211         local size=$((size_mb * 1048576))
19212         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19213                 error "dd to $DIR/$tfile failed"
19214
19215         lfs ladvise -a willread $DIR/$tfile ||
19216                 error "Ladvise failed with no range argument"
19217
19218         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19219                 error "Ladvise failed with no -l or -e argument"
19220
19221         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19222                 error "Ladvise failed with only -e argument"
19223
19224         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19225                 error "Ladvise failed with only -l argument"
19226
19227         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19228                 error "End offset should not be smaller than start offset"
19229
19230         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19231                 error "End offset should not be equal to start offset"
19232
19233         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19234                 error "Ladvise failed with overflowing -s argument"
19235
19236         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19237                 error "Ladvise failed with overflowing -e argument"
19238
19239         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19240                 error "Ladvise failed with overflowing -l argument"
19241
19242         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19243                 error "Ladvise succeeded with conflicting -l and -e arguments"
19244
19245         echo "Synchronous ladvise should wait"
19246         local delay=4
19247 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19248         do_nodes $(comma_list $(osts_nodes)) \
19249                 $LCTL set_param fail_val=$delay fail_loc=0x237
19250
19251         local start_ts=$SECONDS
19252         lfs ladvise -a willread $DIR/$tfile ||
19253                 error "Ladvise failed with no range argument"
19254         local end_ts=$SECONDS
19255         local inteval_ts=$((end_ts - start_ts))
19256
19257         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19258                 error "Synchronous advice didn't wait reply"
19259         fi
19260
19261         echo "Asynchronous ladvise shouldn't wait"
19262         local start_ts=$SECONDS
19263         lfs ladvise -a willread -b $DIR/$tfile ||
19264                 error "Ladvise failed with no range argument"
19265         local end_ts=$SECONDS
19266         local inteval_ts=$((end_ts - start_ts))
19267
19268         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19269                 error "Asynchronous advice blocked"
19270         fi
19271
19272         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
19273         ladvise_willread_performance
19274 }
19275 run_test 255a "check 'lfs ladvise -a willread'"
19276
19277 facet_meminfo() {
19278         local facet=$1
19279         local info=$2
19280
19281         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
19282 }
19283
19284 test_255b() {
19285         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19286                 skip "lustre < 2.8.54 does not support ladvise "
19287         remote_ost_nodsh && skip "remote OST with nodsh"
19288
19289         lfs setstripe -c 1 -i 0 $DIR/$tfile
19290
19291         ladvise_no_type dontneed $DIR/$tfile &&
19292                 skip "dontneed ladvise is not supported"
19293
19294         ladvise_no_ioctl $DIR/$tfile &&
19295                 skip "ladvise ioctl is not supported"
19296
19297         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19298                 [ "$ost1_FSTYPE" = "zfs" ] &&
19299                 skip "zfs-osd does not support 'ladvise dontneed'"
19300
19301         local size_mb=100
19302         local size=$((size_mb * 1048576))
19303         # In order to prevent disturbance of other processes, only check 3/4
19304         # of the memory usage
19305         local kibibytes=$((size_mb * 1024 * 3 / 4))
19306
19307         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19308                 error "dd to $DIR/$tfile failed"
19309
19310         #force write to complete before dropping OST cache & checking memory
19311         sync
19312
19313         local total=$(facet_meminfo ost1 MemTotal)
19314         echo "Total memory: $total KiB"
19315
19316         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
19317         local before_read=$(facet_meminfo ost1 Cached)
19318         echo "Cache used before read: $before_read KiB"
19319
19320         lfs ladvise -a willread $DIR/$tfile ||
19321                 error "Ladvise willread failed"
19322         local after_read=$(facet_meminfo ost1 Cached)
19323         echo "Cache used after read: $after_read KiB"
19324
19325         lfs ladvise -a dontneed $DIR/$tfile ||
19326                 error "Ladvise dontneed again failed"
19327         local no_read=$(facet_meminfo ost1 Cached)
19328         echo "Cache used after dontneed ladvise: $no_read KiB"
19329
19330         if [ $total -lt $((before_read + kibibytes)) ]; then
19331                 echo "Memory is too small, abort checking"
19332                 return 0
19333         fi
19334
19335         if [ $((before_read + kibibytes)) -gt $after_read ]; then
19336                 error "Ladvise willread should use more memory" \
19337                         "than $kibibytes KiB"
19338         fi
19339
19340         if [ $((no_read + kibibytes)) -gt $after_read ]; then
19341                 error "Ladvise dontneed should release more memory" \
19342                         "than $kibibytes KiB"
19343         fi
19344 }
19345 run_test 255b "check 'lfs ladvise -a dontneed'"
19346
19347 test_255c() {
19348         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
19349                 skip "lustre < 2.10.50 does not support lockahead"
19350
19351         local count
19352         local new_count
19353         local difference
19354         local i
19355         local rc
19356
19357         test_mkdir -p $DIR/$tdir
19358         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19359
19360         #test 10 returns only success/failure
19361         i=10
19362         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19363         rc=$?
19364         if [ $rc -eq 255 ]; then
19365                 error "Ladvise test${i} failed, ${rc}"
19366         fi
19367
19368         #test 11 counts lock enqueue requests, all others count new locks
19369         i=11
19370         count=$(do_facet ost1 \
19371                 $LCTL get_param -n ost.OSS.ost.stats)
19372         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
19373
19374         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19375         rc=$?
19376         if [ $rc -eq 255 ]; then
19377                 error "Ladvise test${i} failed, ${rc}"
19378         fi
19379
19380         new_count=$(do_facet ost1 \
19381                 $LCTL get_param -n ost.OSS.ost.stats)
19382         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
19383                    awk '{ print $2 }')
19384
19385         difference="$((new_count - count))"
19386         if [ $difference -ne $rc ]; then
19387                 error "Ladvise test${i}, bad enqueue count, returned " \
19388                       "${rc}, actual ${difference}"
19389         fi
19390
19391         for i in $(seq 12 21); do
19392                 # If we do not do this, we run the risk of having too many
19393                 # locks and starting lock cancellation while we are checking
19394                 # lock counts.
19395                 cancel_lru_locks osc
19396
19397                 count=$($LCTL get_param -n \
19398                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19399
19400                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
19401                 rc=$?
19402                 if [ $rc -eq 255 ]; then
19403                         error "Ladvise test ${i} failed, ${rc}"
19404                 fi
19405
19406                 new_count=$($LCTL get_param -n \
19407                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19408                 difference="$((new_count - count))"
19409
19410                 # Test 15 output is divided by 100 to map down to valid return
19411                 if [ $i -eq 15 ]; then
19412                         rc="$((rc * 100))"
19413                 fi
19414
19415                 if [ $difference -ne $rc ]; then
19416                         error "Ladvise test ${i}, bad lock count, returned " \
19417                               "${rc}, actual ${difference}"
19418                 fi
19419         done
19420
19421         #test 22 returns only success/failure
19422         i=22
19423         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19424         rc=$?
19425         if [ $rc -eq 255 ]; then
19426                 error "Ladvise test${i} failed, ${rc}"
19427         fi
19428 }
19429 run_test 255c "suite of ladvise lockahead tests"
19430
19431 test_256() {
19432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19433         remote_mds_nodsh && skip "remote MDS with nodsh"
19434         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19435         changelog_users $SINGLEMDS | grep "^cl" &&
19436                 skip "active changelog user"
19437
19438         local cl_user
19439         local cat_sl
19440         local mdt_dev
19441
19442         mdt_dev=$(mdsdevname 1)
19443         echo $mdt_dev
19444
19445         changelog_register || error "changelog_register failed"
19446
19447         rm -rf $DIR/$tdir
19448         mkdir -p $DIR/$tdir
19449
19450         changelog_clear 0 || error "changelog_clear failed"
19451
19452         # change something
19453         touch $DIR/$tdir/{1..10}
19454
19455         # stop the MDT
19456         stop $SINGLEMDS || error "Fail to stop MDT"
19457
19458         # remount the MDT
19459
19460         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
19461
19462         #after mount new plainllog is used
19463         touch $DIR/$tdir/{11..19}
19464         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
19465         stack_trap "rm -f $tmpfile"
19466         cat_sl=$(do_facet $SINGLEMDS "sync; \
19467                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19468                  llog_reader $tmpfile | grep -c type=1064553b")
19469         do_facet $SINGLEMDS llog_reader $tmpfile
19470
19471         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
19472
19473         changelog_clear 0 || error "changelog_clear failed"
19474
19475         cat_sl=$(do_facet $SINGLEMDS "sync; \
19476                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19477                  llog_reader $tmpfile | grep -c type=1064553b")
19478
19479         if (( cat_sl == 2 )); then
19480                 error "Empty plain llog was not deleted from changelog catalog"
19481         elif (( cat_sl != 1 )); then
19482                 error "Active plain llog shouldn't be deleted from catalog"
19483         fi
19484 }
19485 run_test 256 "Check llog delete for empty and not full state"
19486
19487 test_257() {
19488         remote_mds_nodsh && skip "remote MDS with nodsh"
19489         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19490                 skip "Need MDS version at least 2.8.55"
19491
19492         test_mkdir $DIR/$tdir
19493
19494         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
19495                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
19496         stat $DIR/$tdir
19497
19498 #define OBD_FAIL_MDS_XATTR_REP                  0x161
19499         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19500         local facet=mds$((mdtidx + 1))
19501         set_nodes_failloc $(facet_active_host $facet) 0x80000161
19502         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
19503
19504         stop $facet || error "stop MDS failed"
19505         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
19506                 error "start MDS fail"
19507         wait_recovery_complete $facet
19508 }
19509 run_test 257 "xattr locks are not lost"
19510
19511 # Verify we take the i_mutex when security requires it
19512 test_258a() {
19513 #define OBD_FAIL_IMUTEX_SEC 0x141c
19514         $LCTL set_param fail_loc=0x141c
19515         touch $DIR/$tfile
19516         chmod u+s $DIR/$tfile
19517         chmod a+rwx $DIR/$tfile
19518         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19519         RC=$?
19520         if [ $RC -ne 0 ]; then
19521                 error "error, failed to take i_mutex, rc=$?"
19522         fi
19523         rm -f $DIR/$tfile
19524 }
19525 run_test 258a "verify i_mutex security behavior when suid attributes is set"
19526
19527 # Verify we do NOT take the i_mutex in the normal case
19528 test_258b() {
19529 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
19530         $LCTL set_param fail_loc=0x141d
19531         touch $DIR/$tfile
19532         chmod a+rwx $DIR
19533         chmod a+rw $DIR/$tfile
19534         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19535         RC=$?
19536         if [ $RC -ne 0 ]; then
19537                 error "error, took i_mutex unnecessarily, rc=$?"
19538         fi
19539         rm -f $DIR/$tfile
19540
19541 }
19542 run_test 258b "verify i_mutex security behavior"
19543
19544 test_259() {
19545         local file=$DIR/$tfile
19546         local before
19547         local after
19548
19549         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19550
19551         stack_trap "rm -f $file" EXIT
19552
19553         wait_delete_completed
19554         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19555         echo "before: $before"
19556
19557         $LFS setstripe -i 0 -c 1 $file
19558         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
19559         sync_all_data
19560         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19561         echo "after write: $after"
19562
19563 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
19564         do_facet ost1 $LCTL set_param fail_loc=0x2301
19565         $TRUNCATE $file 0
19566         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19567         echo "after truncate: $after"
19568
19569         stop ost1
19570         do_facet ost1 $LCTL set_param fail_loc=0
19571         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19572         sleep 2
19573         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19574         echo "after restart: $after"
19575         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
19576                 error "missing truncate?"
19577
19578         return 0
19579 }
19580 run_test 259 "crash at delayed truncate"
19581
19582 test_260() {
19583 #define OBD_FAIL_MDC_CLOSE               0x806
19584         $LCTL set_param fail_loc=0x80000806
19585         touch $DIR/$tfile
19586
19587 }
19588 run_test 260 "Check mdc_close fail"
19589
19590 ### Data-on-MDT sanity tests ###
19591 test_270a() {
19592         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19593                 skip "Need MDS version at least 2.10.55 for DoM"
19594
19595         # create DoM file
19596         local dom=$DIR/$tdir/dom_file
19597         local tmp=$DIR/$tdir/tmp_file
19598
19599         mkdir -p $DIR/$tdir
19600
19601         # basic checks for DoM component creation
19602         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
19603                 error "Can set MDT layout to non-first entry"
19604
19605         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
19606                 error "Can define multiple entries as MDT layout"
19607
19608         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
19609
19610         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
19611         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
19612         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
19613
19614         local mdtidx=$($LFS getstripe -m $dom)
19615         local mdtname=MDT$(printf %04x $mdtidx)
19616         local facet=mds$((mdtidx + 1))
19617         local space_check=1
19618
19619         # Skip free space checks with ZFS
19620         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
19621
19622         # write
19623         sync
19624         local size_tmp=$((65536 * 3))
19625         local mdtfree1=$(do_facet $facet \
19626                          lctl get_param -n osd*.*$mdtname.kbytesfree)
19627
19628         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19629         # check also direct IO along write
19630         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
19631         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19632         sync
19633         cmp $tmp $dom || error "file data is different"
19634         [ $(stat -c%s $dom) == $size_tmp ] ||
19635                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19636         if [ $space_check == 1 ]; then
19637                 local mdtfree2=$(do_facet $facet \
19638                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
19639
19640                 # increase in usage from by $size_tmp
19641                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19642                         error "MDT free space wrong after write: " \
19643                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19644         fi
19645
19646         # truncate
19647         local size_dom=10000
19648
19649         $TRUNCATE $dom $size_dom
19650         [ $(stat -c%s $dom) == $size_dom ] ||
19651                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
19652         if [ $space_check == 1 ]; then
19653                 mdtfree1=$(do_facet $facet \
19654                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19655                 # decrease in usage from $size_tmp to new $size_dom
19656                 [ $(($mdtfree1 - $mdtfree2)) -ge \
19657                   $(((size_tmp - size_dom) / 1024)) ] ||
19658                         error "MDT free space is wrong after truncate: " \
19659                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
19660         fi
19661
19662         # append
19663         cat $tmp >> $dom
19664         sync
19665         size_dom=$((size_dom + size_tmp))
19666         [ $(stat -c%s $dom) == $size_dom ] ||
19667                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
19668         if [ $space_check == 1 ]; then
19669                 mdtfree2=$(do_facet $facet \
19670                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19671                 # increase in usage by $size_tmp from previous
19672                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19673                         error "MDT free space is wrong after append: " \
19674                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19675         fi
19676
19677         # delete
19678         rm $dom
19679         if [ $space_check == 1 ]; then
19680                 mdtfree1=$(do_facet $facet \
19681                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19682                 # decrease in usage by $size_dom from previous
19683                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
19684                         error "MDT free space is wrong after removal: " \
19685                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
19686         fi
19687
19688         # combined striping
19689         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
19690                 error "Can't create DoM + OST striping"
19691
19692         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
19693         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19694         # check also direct IO along write
19695         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19696         sync
19697         cmp $tmp $dom || error "file data is different"
19698         [ $(stat -c%s $dom) == $size_tmp ] ||
19699                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19700         rm $dom $tmp
19701
19702         return 0
19703 }
19704 run_test 270a "DoM: basic functionality tests"
19705
19706 test_270b() {
19707         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19708                 skip "Need MDS version at least 2.10.55"
19709
19710         local dom=$DIR/$tdir/dom_file
19711         local max_size=1048576
19712
19713         mkdir -p $DIR/$tdir
19714         $LFS setstripe -E $max_size -L mdt $dom
19715
19716         # truncate over the limit
19717         $TRUNCATE $dom $(($max_size + 1)) &&
19718                 error "successful truncate over the maximum size"
19719         # write over the limit
19720         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
19721                 error "successful write over the maximum size"
19722         # append over the limit
19723         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
19724         echo "12345" >> $dom && error "successful append over the maximum size"
19725         rm $dom
19726
19727         return 0
19728 }
19729 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
19730
19731 test_270c() {
19732         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19733                 skip "Need MDS version at least 2.10.55"
19734
19735         mkdir -p $DIR/$tdir
19736         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19737
19738         # check files inherit DoM EA
19739         touch $DIR/$tdir/first
19740         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
19741                 error "bad pattern"
19742         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
19743                 error "bad stripe count"
19744         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
19745                 error "bad stripe size"
19746
19747         # check directory inherits DoM EA and uses it as default
19748         mkdir $DIR/$tdir/subdir
19749         touch $DIR/$tdir/subdir/second
19750         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
19751                 error "bad pattern in sub-directory"
19752         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
19753                 error "bad stripe count in sub-directory"
19754         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
19755                 error "bad stripe size in sub-directory"
19756         return 0
19757 }
19758 run_test 270c "DoM: DoM EA inheritance tests"
19759
19760 test_270d() {
19761         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19762                 skip "Need MDS version at least 2.10.55"
19763
19764         mkdir -p $DIR/$tdir
19765         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19766
19767         # inherit default DoM striping
19768         mkdir $DIR/$tdir/subdir
19769         touch $DIR/$tdir/subdir/f1
19770
19771         # change default directory striping
19772         $LFS setstripe -c 1 $DIR/$tdir/subdir
19773         touch $DIR/$tdir/subdir/f2
19774         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
19775                 error "wrong default striping in file 2"
19776         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
19777                 error "bad pattern in file 2"
19778         return 0
19779 }
19780 run_test 270d "DoM: change striping from DoM to RAID0"
19781
19782 test_270e() {
19783         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19784                 skip "Need MDS version at least 2.10.55"
19785
19786         mkdir -p $DIR/$tdir/dom
19787         mkdir -p $DIR/$tdir/norm
19788         DOMFILES=20
19789         NORMFILES=10
19790         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
19791         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
19792
19793         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
19794         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
19795
19796         # find DoM files by layout
19797         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
19798         [ $NUM -eq  $DOMFILES ] ||
19799                 error "lfs find -L: found $NUM, expected $DOMFILES"
19800         echo "Test 1: lfs find 20 DOM files by layout: OK"
19801
19802         # there should be 1 dir with default DOM striping
19803         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
19804         [ $NUM -eq  1 ] ||
19805                 error "lfs find -L: found $NUM, expected 1 dir"
19806         echo "Test 2: lfs find 1 DOM dir by layout: OK"
19807
19808         # find DoM files by stripe size
19809         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
19810         [ $NUM -eq  $DOMFILES ] ||
19811                 error "lfs find -S: found $NUM, expected $DOMFILES"
19812         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
19813
19814         # find files by stripe offset except DoM files
19815         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
19816         [ $NUM -eq  $NORMFILES ] ||
19817                 error "lfs find -i: found $NUM, expected $NORMFILES"
19818         echo "Test 5: lfs find no DOM files by stripe index: OK"
19819         return 0
19820 }
19821 run_test 270e "DoM: lfs find with DoM files test"
19822
19823 test_270f() {
19824         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19825                 skip "Need MDS version at least 2.10.55"
19826
19827         local mdtname=${FSNAME}-MDT0000-mdtlov
19828         local dom=$DIR/$tdir/dom_file
19829         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
19830                                                 lod.$mdtname.dom_stripesize)
19831         local dom_limit=131072
19832
19833         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
19834         local dom_current=$(do_facet mds1 $LCTL get_param -n \
19835                                                 lod.$mdtname.dom_stripesize)
19836         [ ${dom_limit} -eq ${dom_current} ] ||
19837                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
19838
19839         $LFS mkdir -i 0 -c 1 $DIR/$tdir
19840         $LFS setstripe -d $DIR/$tdir
19841         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
19842                 error "Can't set directory default striping"
19843
19844         # exceed maximum stripe size
19845         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
19846                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
19847         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
19848                 error "Able to create DoM component size more than LOD limit"
19849
19850         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
19851         dom_current=$(do_facet mds1 $LCTL get_param -n \
19852                                                 lod.$mdtname.dom_stripesize)
19853         [ 0 -eq ${dom_current} ] ||
19854                 error "Can't set zero DoM stripe limit"
19855         rm $dom
19856
19857         # attempt to create DoM file on server with disabled DoM should
19858         # remove DoM entry from layout and be succeed
19859         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
19860                 error "Can't create DoM file (DoM is disabled)"
19861         [ $($LFS getstripe -L $dom) == "mdt" ] &&
19862                 error "File has DoM component while DoM is disabled"
19863         rm $dom
19864
19865         # attempt to create DoM file with only DoM stripe should return error
19866         $LFS setstripe -E $dom_limit -L mdt $dom &&
19867                 error "Able to create DoM-only file while DoM is disabled"
19868
19869         # too low values to be aligned with smallest stripe size 64K
19870         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
19871         dom_current=$(do_facet mds1 $LCTL get_param -n \
19872                                                 lod.$mdtname.dom_stripesize)
19873         [ 30000 -eq ${dom_current} ] &&
19874                 error "Can set too small DoM stripe limit"
19875
19876         # 64K is a minimal stripe size in Lustre, expect limit of that size
19877         [ 65536 -eq ${dom_current} ] ||
19878                 error "Limit is not set to 64K but ${dom_current}"
19879
19880         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
19881         dom_current=$(do_facet mds1 $LCTL get_param -n \
19882                                                 lod.$mdtname.dom_stripesize)
19883         echo $dom_current
19884         [ 2147483648 -eq ${dom_current} ] &&
19885                 error "Can set too large DoM stripe limit"
19886
19887         do_facet mds1 $LCTL set_param -n \
19888                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
19889         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
19890                 error "Can't create DoM component size after limit change"
19891         do_facet mds1 $LCTL set_param -n \
19892                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
19893         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
19894                 error "Can't create DoM file after limit decrease"
19895         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
19896                 error "Can create big DoM component after limit decrease"
19897         touch ${dom}_def ||
19898                 error "Can't create file with old default layout"
19899
19900         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
19901         return 0
19902 }
19903 run_test 270f "DoM: maximum DoM stripe size checks"
19904
19905 test_270g() {
19906         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19907                 skip "Need MDS version at least 2.13.52"
19908         local dom=$DIR/$tdir/$tfile
19909
19910         $LFS mkdir -i 0 -c 1 $DIR/$tdir
19911         local lodname=${FSNAME}-MDT0000-mdtlov
19912
19913         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
19914         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
19915         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
19916         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
19917
19918         local dom_limit=1024
19919         local dom_threshold="50%"
19920
19921         $LFS setstripe -d $DIR/$tdir
19922         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
19923                 error "Can't set directory default striping"
19924
19925         do_facet mds1 $LCTL set_param -n \
19926                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
19927         # set 0 threshold and create DOM file to change tunable stripesize
19928         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
19929         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
19930                 error "Failed to create $dom file"
19931         # now tunable dom_cur_stripesize should reach maximum
19932         local dom_current=$(do_facet mds1 $LCTL get_param -n \
19933                                         lod.${lodname}.dom_stripesize_cur_kb)
19934         [[ $dom_current == $dom_limit ]] ||
19935                 error "Current DOM stripesize is not maximum"
19936         rm $dom
19937
19938         # set threshold for further tests
19939         do_facet mds1 $LCTL set_param -n \
19940                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
19941         echo "DOM threshold is $dom_threshold free space"
19942         local dom_def
19943         local dom_set
19944         # Spoof bfree to exceed threshold
19945         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
19946         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
19947         for spfree in 40 20 0 15 30 55; do
19948                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
19949                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
19950                         error "Failed to create $dom file"
19951                 dom_def=$(do_facet mds1 $LCTL get_param -n \
19952                                         lod.${lodname}.dom_stripesize_cur_kb)
19953                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
19954                 [[ $dom_def != $dom_current ]] ||
19955                         error "Default stripe size was not changed"
19956                 if [[ $spfree > 0 ]] ; then
19957                         dom_set=$($LFS getstripe -S $dom)
19958                         [[ $dom_set == $((dom_def * 1024)) ]] ||
19959                                 error "DOM component size is still old"
19960                 else
19961                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
19962                                 error "DoM component is set with no free space"
19963                 fi
19964                 rm $dom
19965                 dom_current=$dom_def
19966         done
19967 }
19968 run_test 270g "DoM: default DoM stripe size depends on free space"
19969
19970 test_270h() {
19971         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19972                 skip "Need MDS version at least 2.13.53"
19973
19974         local mdtname=${FSNAME}-MDT0000-mdtlov
19975         local dom=$DIR/$tdir/$tfile
19976         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
19977
19978         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
19979         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
19980
19981         $LFS mkdir -i 0 -c 1 $DIR/$tdir
19982         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
19983                 error "can't create OST file"
19984         # mirrored file with DOM entry in the second mirror
19985         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
19986                 error "can't create mirror with DoM component"
19987
19988         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
19989
19990         # DOM component in the middle and has other enries in the same mirror,
19991         # should succeed but lost DoM component
19992         $LFS setstripe --copy=${dom}_1 $dom ||
19993                 error "Can't create file from OST|DOM mirror layout"
19994         # check new file has no DoM layout after all
19995         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
19996                 error "File has DoM component while DoM is disabled"
19997 }
19998 run_test 270h "DoM: DoM stripe removal when disabled on server"
19999
20000 test_271a() {
20001         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20002                 skip "Need MDS version at least 2.10.55"
20003
20004         local dom=$DIR/$tdir/dom
20005
20006         mkdir -p $DIR/$tdir
20007
20008         $LFS setstripe -E 1024K -L mdt $dom
20009
20010         lctl set_param -n mdc.*.stats=clear
20011         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20012         cat $dom > /dev/null
20013         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20014         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20015         ls $dom
20016         rm -f $dom
20017 }
20018 run_test 271a "DoM: data is cached for read after write"
20019
20020 test_271b() {
20021         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20022                 skip "Need MDS version at least 2.10.55"
20023
20024         local dom=$DIR/$tdir/dom
20025
20026         mkdir -p $DIR/$tdir
20027
20028         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20029
20030         lctl set_param -n mdc.*.stats=clear
20031         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20032         cancel_lru_locks mdc
20033         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20034         # second stat to check size is cached on client
20035         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20036         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20037         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20038         rm -f $dom
20039 }
20040 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20041
20042 test_271ba() {
20043         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20044                 skip "Need MDS version at least 2.10.55"
20045
20046         local dom=$DIR/$tdir/dom
20047
20048         mkdir -p $DIR/$tdir
20049
20050         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20051
20052         lctl set_param -n mdc.*.stats=clear
20053         lctl set_param -n osc.*.stats=clear
20054         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20055         cancel_lru_locks mdc
20056         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20057         # second stat to check size is cached on client
20058         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20059         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20060         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20061         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20062         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20063         rm -f $dom
20064 }
20065 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20066
20067
20068 get_mdc_stats() {
20069         local mdtidx=$1
20070         local param=$2
20071         local mdt=MDT$(printf %04x $mdtidx)
20072
20073         if [ -z $param ]; then
20074                 lctl get_param -n mdc.*$mdt*.stats
20075         else
20076                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20077         fi
20078 }
20079
20080 test_271c() {
20081         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20082                 skip "Need MDS version at least 2.10.55"
20083
20084         local dom=$DIR/$tdir/dom
20085
20086         mkdir -p $DIR/$tdir
20087
20088         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20089
20090         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20091         local facet=mds$((mdtidx + 1))
20092
20093         cancel_lru_locks mdc
20094         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20095         createmany -o $dom 1000
20096         lctl set_param -n mdc.*.stats=clear
20097         smalliomany -w $dom 1000 200
20098         get_mdc_stats $mdtidx
20099         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20100         # Each file has 1 open, 1 IO enqueues, total 2000
20101         # but now we have also +1 getxattr for security.capability, total 3000
20102         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20103         unlinkmany $dom 1000
20104
20105         cancel_lru_locks mdc
20106         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20107         createmany -o $dom 1000
20108         lctl set_param -n mdc.*.stats=clear
20109         smalliomany -w $dom 1000 200
20110         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20111         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20112         # for OPEN and IO lock.
20113         [ $((enq - enq_2)) -ge 1000 ] ||
20114                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20115         unlinkmany $dom 1000
20116         return 0
20117 }
20118 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20119
20120 cleanup_271def_tests() {
20121         trap 0
20122         rm -f $1
20123 }
20124
20125 test_271d() {
20126         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20127                 skip "Need MDS version at least 2.10.57"
20128
20129         local dom=$DIR/$tdir/dom
20130         local tmp=$TMP/$tfile
20131         trap "cleanup_271def_tests $tmp" EXIT
20132
20133         mkdir -p $DIR/$tdir
20134
20135         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20136
20137         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20138
20139         cancel_lru_locks mdc
20140         dd if=/dev/urandom of=$tmp bs=1000 count=1
20141         dd if=$tmp of=$dom bs=1000 count=1
20142         cancel_lru_locks mdc
20143
20144         cat /etc/hosts >> $tmp
20145         lctl set_param -n mdc.*.stats=clear
20146
20147         # append data to the same file it should update local page
20148         echo "Append to the same page"
20149         cat /etc/hosts >> $dom
20150         local num=$(get_mdc_stats $mdtidx ost_read)
20151         local ra=$(get_mdc_stats $mdtidx req_active)
20152         local rw=$(get_mdc_stats $mdtidx req_waittime)
20153
20154         [ -z $num ] || error "$num READ RPC occured"
20155         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20156         echo "... DONE"
20157
20158         # compare content
20159         cmp $tmp $dom || error "file miscompare"
20160
20161         cancel_lru_locks mdc
20162         lctl set_param -n mdc.*.stats=clear
20163
20164         echo "Open and read file"
20165         cat $dom > /dev/null
20166         local num=$(get_mdc_stats $mdtidx ost_read)
20167         local ra=$(get_mdc_stats $mdtidx req_active)
20168         local rw=$(get_mdc_stats $mdtidx req_waittime)
20169
20170         [ -z $num ] || error "$num READ RPC occured"
20171         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20172         echo "... DONE"
20173
20174         # compare content
20175         cmp $tmp $dom || error "file miscompare"
20176
20177         return 0
20178 }
20179 run_test 271d "DoM: read on open (1K file in reply buffer)"
20180
20181 test_271f() {
20182         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20183                 skip "Need MDS version at least 2.10.57"
20184
20185         local dom=$DIR/$tdir/dom
20186         local tmp=$TMP/$tfile
20187         trap "cleanup_271def_tests $tmp" EXIT
20188
20189         mkdir -p $DIR/$tdir
20190
20191         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20192
20193         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20194
20195         cancel_lru_locks mdc
20196         dd if=/dev/urandom of=$tmp bs=265000 count=1
20197         dd if=$tmp of=$dom bs=265000 count=1
20198         cancel_lru_locks mdc
20199         cat /etc/hosts >> $tmp
20200         lctl set_param -n mdc.*.stats=clear
20201
20202         echo "Append to the same page"
20203         cat /etc/hosts >> $dom
20204         local num=$(get_mdc_stats $mdtidx ost_read)
20205         local ra=$(get_mdc_stats $mdtidx req_active)
20206         local rw=$(get_mdc_stats $mdtidx req_waittime)
20207
20208         [ -z $num ] || error "$num READ RPC occured"
20209         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20210         echo "... DONE"
20211
20212         # compare content
20213         cmp $tmp $dom || error "file miscompare"
20214
20215         cancel_lru_locks mdc
20216         lctl set_param -n mdc.*.stats=clear
20217
20218         echo "Open and read file"
20219         cat $dom > /dev/null
20220         local num=$(get_mdc_stats $mdtidx ost_read)
20221         local ra=$(get_mdc_stats $mdtidx req_active)
20222         local rw=$(get_mdc_stats $mdtidx req_waittime)
20223
20224         [ -z $num ] && num=0
20225         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20226         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20227         echo "... DONE"
20228
20229         # compare content
20230         cmp $tmp $dom || error "file miscompare"
20231
20232         return 0
20233 }
20234 run_test 271f "DoM: read on open (200K file and read tail)"
20235
20236 test_271g() {
20237         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20238                 skip "Skipping due to old client or server version"
20239
20240         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20241         # to get layout
20242         $CHECKSTAT -t file $DIR1/$tfile
20243
20244         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20245         MULTIOP_PID=$!
20246         sleep 1
20247         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20248         $LCTL set_param fail_loc=0x80000314
20249         rm $DIR1/$tfile || error "Unlink fails"
20250         RC=$?
20251         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20252         [ $RC -eq 0 ] || error "Failed write to stale object"
20253 }
20254 run_test 271g "Discard DoM data vs client flush race"
20255
20256 test_272a() {
20257         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20258                 skip "Need MDS version at least 2.11.50"
20259
20260         local dom=$DIR/$tdir/dom
20261         mkdir -p $DIR/$tdir
20262
20263         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20264         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20265                 error "failed to write data into $dom"
20266         local old_md5=$(md5sum $dom)
20267
20268         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20269                 error "failed to migrate to the same DoM component"
20270
20271         local new_md5=$(md5sum $dom)
20272
20273         [ "$old_md5" == "$new_md5" ] ||
20274                 error "md5sum differ: $old_md5, $new_md5"
20275
20276         [ $($LFS getstripe -c $dom) -eq 2 ] ||
20277                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
20278 }
20279 run_test 272a "DoM migration: new layout with the same DOM component"
20280
20281 test_272b() {
20282         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20283                 skip "Need MDS version at least 2.11.50"
20284
20285         local dom=$DIR/$tdir/dom
20286         mkdir -p $DIR/$tdir
20287         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20288
20289         local mdtidx=$($LFS getstripe -m $dom)
20290         local mdtname=MDT$(printf %04x $mdtidx)
20291         local facet=mds$((mdtidx + 1))
20292
20293         local mdtfree1=$(do_facet $facet \
20294                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20295         dd if=/dev/urandom of=$dom bs=2M count=1 ||
20296                 error "failed to write data into $dom"
20297         local old_md5=$(md5sum $dom)
20298         cancel_lru_locks mdc
20299         local mdtfree1=$(do_facet $facet \
20300                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20301
20302         $LFS migrate -c2 $dom ||
20303                 error "failed to migrate to the new composite layout"
20304         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20305                 error "MDT stripe was not removed"
20306
20307         cancel_lru_locks mdc
20308         local new_md5=$(md5sum $dom)
20309         [ "$old_md5" == "$new_md5" ] ||
20310                 error "$old_md5 != $new_md5"
20311
20312         # Skip free space checks with ZFS
20313         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20314                 local mdtfree2=$(do_facet $facet \
20315                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20316                 [ $mdtfree2 -gt $mdtfree1 ] ||
20317                         error "MDT space is not freed after migration"
20318         fi
20319         return 0
20320 }
20321 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
20322
20323 test_272c() {
20324         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20325                 skip "Need MDS version at least 2.11.50"
20326
20327         local dom=$DIR/$tdir/$tfile
20328         mkdir -p $DIR/$tdir
20329         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20330
20331         local mdtidx=$($LFS getstripe -m $dom)
20332         local mdtname=MDT$(printf %04x $mdtidx)
20333         local facet=mds$((mdtidx + 1))
20334
20335         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20336                 error "failed to write data into $dom"
20337         local old_md5=$(md5sum $dom)
20338         cancel_lru_locks mdc
20339         local mdtfree1=$(do_facet $facet \
20340                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20341
20342         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
20343                 error "failed to migrate to the new composite layout"
20344         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
20345                 error "MDT stripe was not removed"
20346
20347         cancel_lru_locks mdc
20348         local new_md5=$(md5sum $dom)
20349         [ "$old_md5" == "$new_md5" ] ||
20350                 error "$old_md5 != $new_md5"
20351
20352         # Skip free space checks with ZFS
20353         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20354                 local mdtfree2=$(do_facet $facet \
20355                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20356                 [ $mdtfree2 -gt $mdtfree1 ] ||
20357                         error "MDS space is not freed after migration"
20358         fi
20359         return 0
20360 }
20361 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
20362
20363 test_272d() {
20364         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20365                 skip "Need MDS version at least 2.12.55"
20366
20367         local dom=$DIR/$tdir/$tfile
20368         mkdir -p $DIR/$tdir
20369         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20370
20371         local mdtidx=$($LFS getstripe -m $dom)
20372         local mdtname=MDT$(printf %04x $mdtidx)
20373         local facet=mds$((mdtidx + 1))
20374
20375         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20376                 error "failed to write data into $dom"
20377         local old_md5=$(md5sum $dom)
20378         cancel_lru_locks mdc
20379         local mdtfree1=$(do_facet $facet \
20380                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20381
20382         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
20383                 error "failed mirroring to the new composite layout"
20384         $LFS mirror resync $dom ||
20385                 error "failed mirror resync"
20386         $LFS mirror split --mirror-id 1 -d $dom ||
20387                 error "failed mirror split"
20388
20389         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20390                 error "MDT stripe was not removed"
20391
20392         cancel_lru_locks mdc
20393         local new_md5=$(md5sum $dom)
20394         [ "$old_md5" == "$new_md5" ] ||
20395                 error "$old_md5 != $new_md5"
20396
20397         # Skip free space checks with ZFS
20398         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20399                 local mdtfree2=$(do_facet $facet \
20400                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20401                 [ $mdtfree2 -gt $mdtfree1 ] ||
20402                         error "MDS space is not freed after DOM mirror deletion"
20403         fi
20404         return 0
20405 }
20406 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
20407
20408 test_272e() {
20409         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20410                 skip "Need MDS version at least 2.12.55"
20411
20412         local dom=$DIR/$tdir/$tfile
20413         mkdir -p $DIR/$tdir
20414         $LFS setstripe -c 2 $dom
20415
20416         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20417                 error "failed to write data into $dom"
20418         local old_md5=$(md5sum $dom)
20419         cancel_lru_locks mdc
20420
20421         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
20422                 error "failed mirroring to the DOM layout"
20423         $LFS mirror resync $dom ||
20424                 error "failed mirror resync"
20425         $LFS mirror split --mirror-id 1 -d $dom ||
20426                 error "failed mirror split"
20427
20428         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20429                 error "MDT stripe was not removed"
20430
20431         cancel_lru_locks mdc
20432         local new_md5=$(md5sum $dom)
20433         [ "$old_md5" == "$new_md5" ] ||
20434                 error "$old_md5 != $new_md5"
20435
20436         return 0
20437 }
20438 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
20439
20440 test_272f() {
20441         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20442                 skip "Need MDS version at least 2.12.55"
20443
20444         local dom=$DIR/$tdir/$tfile
20445         mkdir -p $DIR/$tdir
20446         $LFS setstripe -c 2 $dom
20447
20448         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20449                 error "failed to write data into $dom"
20450         local old_md5=$(md5sum $dom)
20451         cancel_lru_locks mdc
20452
20453         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
20454                 error "failed migrating to the DOM file"
20455
20456         cancel_lru_locks mdc
20457         local new_md5=$(md5sum $dom)
20458         [ "$old_md5" != "$new_md5" ] &&
20459                 error "$old_md5 != $new_md5"
20460
20461         return 0
20462 }
20463 run_test 272f "DoM migration: OST-striped file to DOM file"
20464
20465 test_273a() {
20466         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20467                 skip "Need MDS version at least 2.11.50"
20468
20469         # Layout swap cannot be done if either file has DOM component,
20470         # this will never be supported, migration should be used instead
20471
20472         local dom=$DIR/$tdir/$tfile
20473         mkdir -p $DIR/$tdir
20474
20475         $LFS setstripe -c2 ${dom}_plain
20476         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
20477         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
20478                 error "can swap layout with DoM component"
20479         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
20480                 error "can swap layout with DoM component"
20481
20482         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
20483         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
20484                 error "can swap layout with DoM component"
20485         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
20486                 error "can swap layout with DoM component"
20487         return 0
20488 }
20489 run_test 273a "DoM: layout swapping should fail with DOM"
20490
20491 test_275() {
20492         remote_ost_nodsh && skip "remote OST with nodsh"
20493         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
20494                 skip "Need OST version >= 2.10.57"
20495
20496         local file=$DIR/$tfile
20497         local oss
20498
20499         oss=$(comma_list $(osts_nodes))
20500
20501         dd if=/dev/urandom of=$file bs=1M count=2 ||
20502                 error "failed to create a file"
20503         cancel_lru_locks osc
20504
20505         #lock 1
20506         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20507                 error "failed to read a file"
20508
20509 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
20510         $LCTL set_param fail_loc=0x8000031f
20511
20512         cancel_lru_locks osc &
20513         sleep 1
20514
20515 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
20516         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
20517         #IO takes another lock, but matches the PENDING one
20518         #and places it to the IO RPC
20519         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20520                 error "failed to read a file with PENDING lock"
20521 }
20522 run_test 275 "Read on a canceled duplicate lock"
20523
20524 test_276() {
20525         remote_ost_nodsh && skip "remote OST with nodsh"
20526         local pid
20527
20528         do_facet ost1 "(while true; do \
20529                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
20530                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
20531         pid=$!
20532
20533         for LOOP in $(seq 20); do
20534                 stop ost1
20535                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
20536         done
20537         kill -9 $pid
20538         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
20539                 rm $TMP/sanity_276_pid"
20540 }
20541 run_test 276 "Race between mount and obd_statfs"
20542
20543 test_277() {
20544         $LCTL set_param ldlm.namespaces.*.lru_size=0
20545         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
20546         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20547                         grep ^used_mb | awk '{print $2}')
20548         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
20549         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
20550                 oflag=direct conv=notrunc
20551         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20552                         grep ^used_mb | awk '{print $2}')
20553         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
20554 }
20555 run_test 277 "Direct IO shall drop page cache"
20556
20557 test_278() {
20558         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20559         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20560         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
20561                 skip "needs the same host for mdt1 mdt2" && return
20562
20563         local pid1
20564         local pid2
20565
20566 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
20567         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
20568         stop mds2 &
20569         pid2=$!
20570
20571         stop mds1
20572
20573         echo "Starting MDTs"
20574         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20575         wait $pid2
20576 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
20577 #will return NULL
20578         do_facet mds2 $LCTL set_param fail_loc=0
20579
20580         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
20581         wait_recovery_complete mds2
20582 }
20583 run_test 278 "Race starting MDS between MDTs stop/start"
20584
20585 test_280() {
20586         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
20587                 skip "Need MGS version at least 2.13.52"
20588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20589         combined_mgs_mds || skip "needs combined MGS/MDT"
20590
20591         umount_client $MOUNT
20592 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
20593         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
20594
20595         mount_client $MOUNT &
20596         sleep 1
20597         stop mgs || error "stop mgs failed"
20598         #for a race mgs would crash
20599         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
20600         mount_client $MOUNT || error "mount client failed"
20601 }
20602 run_test 280 "Race between MGS umount and client llog processing"
20603
20604 cleanup_test_300() {
20605         trap 0
20606         umask $SAVE_UMASK
20607 }
20608 test_striped_dir() {
20609         local mdt_index=$1
20610         local stripe_count
20611         local stripe_index
20612
20613         mkdir -p $DIR/$tdir
20614
20615         SAVE_UMASK=$(umask)
20616         trap cleanup_test_300 RETURN EXIT
20617
20618         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
20619                                                 $DIR/$tdir/striped_dir ||
20620                 error "set striped dir error"
20621
20622         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
20623         [ "$mode" = "755" ] || error "expect 755 got $mode"
20624
20625         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
20626                 error "getdirstripe failed"
20627         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
20628         if [ "$stripe_count" != "2" ]; then
20629                 error "1:stripe_count is $stripe_count, expect 2"
20630         fi
20631         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
20632         if [ "$stripe_count" != "2" ]; then
20633                 error "2:stripe_count is $stripe_count, expect 2"
20634         fi
20635
20636         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
20637         if [ "$stripe_index" != "$mdt_index" ]; then
20638                 error "stripe_index is $stripe_index, expect $mdt_index"
20639         fi
20640
20641         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20642                 error "nlink error after create striped dir"
20643
20644         mkdir $DIR/$tdir/striped_dir/a
20645         mkdir $DIR/$tdir/striped_dir/b
20646
20647         stat $DIR/$tdir/striped_dir/a ||
20648                 error "create dir under striped dir failed"
20649         stat $DIR/$tdir/striped_dir/b ||
20650                 error "create dir under striped dir failed"
20651
20652         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
20653                 error "nlink error after mkdir"
20654
20655         rmdir $DIR/$tdir/striped_dir/a
20656         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
20657                 error "nlink error after rmdir"
20658
20659         rmdir $DIR/$tdir/striped_dir/b
20660         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20661                 error "nlink error after rmdir"
20662
20663         chattr +i $DIR/$tdir/striped_dir
20664         createmany -o $DIR/$tdir/striped_dir/f 10 &&
20665                 error "immutable flags not working under striped dir!"
20666         chattr -i $DIR/$tdir/striped_dir
20667
20668         rmdir $DIR/$tdir/striped_dir ||
20669                 error "rmdir striped dir error"
20670
20671         cleanup_test_300
20672
20673         true
20674 }
20675
20676 test_300a() {
20677         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20678                 skip "skipped for lustre < 2.7.0"
20679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20680         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20681
20682         test_striped_dir 0 || error "failed on striped dir on MDT0"
20683         test_striped_dir 1 || error "failed on striped dir on MDT0"
20684 }
20685 run_test 300a "basic striped dir sanity test"
20686
20687 test_300b() {
20688         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20689                 skip "skipped for lustre < 2.7.0"
20690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20691         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20692
20693         local i
20694         local mtime1
20695         local mtime2
20696         local mtime3
20697
20698         test_mkdir $DIR/$tdir || error "mkdir fail"
20699         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20700                 error "set striped dir error"
20701         for i in {0..9}; do
20702                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
20703                 sleep 1
20704                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
20705                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
20706                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
20707                 sleep 1
20708                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
20709                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
20710                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
20711         done
20712         true
20713 }
20714 run_test 300b "check ctime/mtime for striped dir"
20715
20716 test_300c() {
20717         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20718                 skip "skipped for lustre < 2.7.0"
20719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20720         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20721
20722         local file_count
20723
20724         mkdir -p $DIR/$tdir
20725         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
20726                 error "set striped dir error"
20727
20728         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
20729                 error "chown striped dir failed"
20730
20731         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
20732                 error "create 5k files failed"
20733
20734         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
20735
20736         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
20737
20738         rm -rf $DIR/$tdir
20739 }
20740 run_test 300c "chown && check ls under striped directory"
20741
20742 test_300d() {
20743         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20744                 skip "skipped for lustre < 2.7.0"
20745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20746         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20747
20748         local stripe_count
20749         local file
20750
20751         mkdir -p $DIR/$tdir
20752         $LFS setstripe -c 2 $DIR/$tdir
20753
20754         #local striped directory
20755         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20756                 error "set striped dir error"
20757         #look at the directories for debug purposes
20758         ls -l $DIR/$tdir
20759         $LFS getdirstripe $DIR/$tdir
20760         ls -l $DIR/$tdir/striped_dir
20761         $LFS getdirstripe $DIR/$tdir/striped_dir
20762         createmany -o $DIR/$tdir/striped_dir/f 10 ||
20763                 error "create 10 files failed"
20764
20765         #remote striped directory
20766         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
20767                 error "set striped dir error"
20768         #look at the directories for debug purposes
20769         ls -l $DIR/$tdir
20770         $LFS getdirstripe $DIR/$tdir
20771         ls -l $DIR/$tdir/remote_striped_dir
20772         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
20773         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
20774                 error "create 10 files failed"
20775
20776         for file in $(find $DIR/$tdir); do
20777                 stripe_count=$($LFS getstripe -c $file)
20778                 [ $stripe_count -eq 2 ] ||
20779                         error "wrong stripe $stripe_count for $file"
20780         done
20781
20782         rm -rf $DIR/$tdir
20783 }
20784 run_test 300d "check default stripe under striped directory"
20785
20786 test_300e() {
20787         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20788                 skip "Need MDS version at least 2.7.55"
20789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20790         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20791
20792         local stripe_count
20793         local file
20794
20795         mkdir -p $DIR/$tdir
20796
20797         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20798                 error "set striped dir error"
20799
20800         touch $DIR/$tdir/striped_dir/a
20801         touch $DIR/$tdir/striped_dir/b
20802         touch $DIR/$tdir/striped_dir/c
20803
20804         mkdir $DIR/$tdir/striped_dir/dir_a
20805         mkdir $DIR/$tdir/striped_dir/dir_b
20806         mkdir $DIR/$tdir/striped_dir/dir_c
20807
20808         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
20809                 error "set striped adir under striped dir error"
20810
20811         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
20812                 error "set striped bdir under striped dir error"
20813
20814         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
20815                 error "set striped cdir under striped dir error"
20816
20817         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
20818                 error "rename dir under striped dir fails"
20819
20820         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
20821                 error "rename dir under different stripes fails"
20822
20823         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
20824                 error "rename file under striped dir should succeed"
20825
20826         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
20827                 error "rename dir under striped dir should succeed"
20828
20829         rm -rf $DIR/$tdir
20830 }
20831 run_test 300e "check rename under striped directory"
20832
20833 test_300f() {
20834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20835         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20836         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20837                 skip "Need MDS version at least 2.7.55"
20838
20839         local stripe_count
20840         local file
20841
20842         rm -rf $DIR/$tdir
20843         mkdir -p $DIR/$tdir
20844
20845         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20846                 error "set striped dir error"
20847
20848         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
20849                 error "set striped dir error"
20850
20851         touch $DIR/$tdir/striped_dir/a
20852         mkdir $DIR/$tdir/striped_dir/dir_a
20853         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
20854                 error "create striped dir under striped dir fails"
20855
20856         touch $DIR/$tdir/striped_dir1/b
20857         mkdir $DIR/$tdir/striped_dir1/dir_b
20858         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
20859                 error "create striped dir under striped dir fails"
20860
20861         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
20862                 error "rename dir under different striped dir should fail"
20863
20864         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
20865                 error "rename striped dir under diff striped dir should fail"
20866
20867         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
20868                 error "rename file under diff striped dirs fails"
20869
20870         rm -rf $DIR/$tdir
20871 }
20872 run_test 300f "check rename cross striped directory"
20873
20874 test_300_check_default_striped_dir()
20875 {
20876         local dirname=$1
20877         local default_count=$2
20878         local default_index=$3
20879         local stripe_count
20880         local stripe_index
20881         local dir_stripe_index
20882         local dir
20883
20884         echo "checking $dirname $default_count $default_index"
20885         $LFS setdirstripe -D -c $default_count -i $default_index \
20886                                 -t all_char $DIR/$tdir/$dirname ||
20887                 error "set default stripe on striped dir error"
20888         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
20889         [ $stripe_count -eq $default_count ] ||
20890                 error "expect $default_count get $stripe_count for $dirname"
20891
20892         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
20893         [ $stripe_index -eq $default_index ] ||
20894                 error "expect $default_index get $stripe_index for $dirname"
20895
20896         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
20897                                                 error "create dirs failed"
20898
20899         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
20900         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
20901         for dir in $(find $DIR/$tdir/$dirname/*); do
20902                 stripe_count=$($LFS getdirstripe -c $dir)
20903                 [ $stripe_count -eq $default_count ] ||
20904                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
20905                 error "stripe count $default_count != $stripe_count for $dir"
20906
20907                 stripe_index=$($LFS getdirstripe -i $dir)
20908                 [ $default_index -eq -1 ] ||
20909                         [ $stripe_index -eq $default_index ] ||
20910                         error "$stripe_index != $default_index for $dir"
20911
20912                 #check default stripe
20913                 stripe_count=$($LFS getdirstripe -D -c $dir)
20914                 [ $stripe_count -eq $default_count ] ||
20915                 error "default count $default_count != $stripe_count for $dir"
20916
20917                 stripe_index=$($LFS getdirstripe -D -i $dir)
20918                 [ $stripe_index -eq $default_index ] ||
20919                 error "default index $default_index != $stripe_index for $dir"
20920         done
20921         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
20922 }
20923
20924 test_300g() {
20925         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20926         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20927                 skip "Need MDS version at least 2.7.55"
20928
20929         local dir
20930         local stripe_count
20931         local stripe_index
20932
20933         mkdir $DIR/$tdir
20934         mkdir $DIR/$tdir/normal_dir
20935
20936         #Checking when client cache stripe index
20937         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
20938         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
20939                 error "create striped_dir failed"
20940
20941         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
20942                 error "create dir0 fails"
20943         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
20944         [ $stripe_index -eq 0 ] ||
20945                 error "dir0 expect index 0 got $stripe_index"
20946
20947         mkdir $DIR/$tdir/striped_dir/dir1 ||
20948                 error "create dir1 fails"
20949         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
20950         [ $stripe_index -eq 1 ] ||
20951                 error "dir1 expect index 1 got $stripe_index"
20952
20953         #check default stripe count/stripe index
20954         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
20955         test_300_check_default_striped_dir normal_dir 1 0
20956         test_300_check_default_striped_dir normal_dir 2 1
20957         test_300_check_default_striped_dir normal_dir 2 -1
20958
20959         #delete default stripe information
20960         echo "delete default stripeEA"
20961         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
20962                 error "set default stripe on striped dir error"
20963
20964         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
20965         for dir in $(find $DIR/$tdir/normal_dir/*); do
20966                 stripe_count=$($LFS getdirstripe -c $dir)
20967                 [ $stripe_count -eq 0 ] ||
20968                         error "expect 1 get $stripe_count for $dir"
20969                 stripe_index=$($LFS getdirstripe -i $dir)
20970                 [ $stripe_index -eq 0 ] ||
20971                         error "expect 0 get $stripe_index for $dir"
20972         done
20973 }
20974 run_test 300g "check default striped directory for normal directory"
20975
20976 test_300h() {
20977         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20978         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20979                 skip "Need MDS version at least 2.7.55"
20980
20981         local dir
20982         local stripe_count
20983
20984         mkdir $DIR/$tdir
20985         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
20986                 error "set striped dir error"
20987
20988         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
20989         test_300_check_default_striped_dir striped_dir 1 0
20990         test_300_check_default_striped_dir striped_dir 2 1
20991         test_300_check_default_striped_dir striped_dir 2 -1
20992
20993         #delete default stripe information
20994         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
20995                 error "set default stripe on striped dir error"
20996
20997         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
20998         for dir in $(find $DIR/$tdir/striped_dir/*); do
20999                 stripe_count=$($LFS getdirstripe -c $dir)
21000                 [ $stripe_count -eq 0 ] ||
21001                         error "expect 1 get $stripe_count for $dir"
21002         done
21003 }
21004 run_test 300h "check default striped directory for striped directory"
21005
21006 test_300i() {
21007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21008         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21009         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21010                 skip "Need MDS version at least 2.7.55"
21011
21012         local stripe_count
21013         local file
21014
21015         mkdir $DIR/$tdir
21016
21017         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21018                 error "set striped dir error"
21019
21020         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21021                 error "create files under striped dir failed"
21022
21023         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21024                 error "set striped hashdir error"
21025
21026         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21027                 error "create dir0 under hash dir failed"
21028         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21029                 error "create dir1 under hash dir failed"
21030
21031         # unfortunately, we need to umount to clear dir layout cache for now
21032         # once we fully implement dir layout, we can drop this
21033         umount_client $MOUNT || error "umount failed"
21034         mount_client $MOUNT || error "mount failed"
21035
21036         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21037         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21038         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21039
21040         #set the stripe to be unknown hash type
21041         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21042         $LCTL set_param fail_loc=0x1901
21043         for ((i = 0; i < 10; i++)); do
21044                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21045                         error "stat f-$i failed"
21046                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21047         done
21048
21049         touch $DIR/$tdir/striped_dir/f0 &&
21050                 error "create under striped dir with unknown hash should fail"
21051
21052         $LCTL set_param fail_loc=0
21053
21054         umount_client $MOUNT || error "umount failed"
21055         mount_client $MOUNT || error "mount failed"
21056
21057         return 0
21058 }
21059 run_test 300i "client handle unknown hash type striped directory"
21060
21061 test_300j() {
21062         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21064         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21065                 skip "Need MDS version at least 2.7.55"
21066
21067         local stripe_count
21068         local file
21069
21070         mkdir $DIR/$tdir
21071
21072         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21073         $LCTL set_param fail_loc=0x1702
21074         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21075                 error "set striped dir error"
21076
21077         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21078                 error "create files under striped dir failed"
21079
21080         $LCTL set_param fail_loc=0
21081
21082         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21083
21084         return 0
21085 }
21086 run_test 300j "test large update record"
21087
21088 test_300k() {
21089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21090         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21091         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21092                 skip "Need MDS version at least 2.7.55"
21093
21094         # this test needs a huge transaction
21095         local kb
21096         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21097              osd*.$FSNAME-MDT0000.kbytestotal")
21098         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21099
21100         local stripe_count
21101         local file
21102
21103         mkdir $DIR/$tdir
21104
21105         #define OBD_FAIL_LARGE_STRIPE   0x1703
21106         $LCTL set_param fail_loc=0x1703
21107         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21108                 error "set striped dir error"
21109         $LCTL set_param fail_loc=0
21110
21111         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21112                 error "getstripeddir fails"
21113         rm -rf $DIR/$tdir/striped_dir ||
21114                 error "unlink striped dir fails"
21115
21116         return 0
21117 }
21118 run_test 300k "test large striped directory"
21119
21120 test_300l() {
21121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21122         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21123         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21124                 skip "Need MDS version at least 2.7.55"
21125
21126         local stripe_index
21127
21128         test_mkdir -p $DIR/$tdir/striped_dir
21129         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21130                         error "chown $RUNAS_ID failed"
21131         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21132                 error "set default striped dir failed"
21133
21134         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21135         $LCTL set_param fail_loc=0x80000158
21136         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21137
21138         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21139         [ $stripe_index -eq 1 ] ||
21140                 error "expect 1 get $stripe_index for $dir"
21141 }
21142 run_test 300l "non-root user to create dir under striped dir with stale layout"
21143
21144 test_300m() {
21145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21146         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21147         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21148                 skip "Need MDS version at least 2.7.55"
21149
21150         mkdir -p $DIR/$tdir/striped_dir
21151         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21152                 error "set default stripes dir error"
21153
21154         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21155
21156         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21157         [ $stripe_count -eq 0 ] ||
21158                         error "expect 0 get $stripe_count for a"
21159
21160         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21161                 error "set default stripes dir error"
21162
21163         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21164
21165         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21166         [ $stripe_count -eq 0 ] ||
21167                         error "expect 0 get $stripe_count for b"
21168
21169         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21170                 error "set default stripes dir error"
21171
21172         mkdir $DIR/$tdir/striped_dir/c &&
21173                 error "default stripe_index is invalid, mkdir c should fails"
21174
21175         rm -rf $DIR/$tdir || error "rmdir fails"
21176 }
21177 run_test 300m "setstriped directory on single MDT FS"
21178
21179 cleanup_300n() {
21180         local list=$(comma_list $(mdts_nodes))
21181
21182         trap 0
21183         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21184 }
21185
21186 test_300n() {
21187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21188         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21189         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21190                 skip "Need MDS version at least 2.7.55"
21191         remote_mds_nodsh && skip "remote MDS with nodsh"
21192
21193         local stripe_index
21194         local list=$(comma_list $(mdts_nodes))
21195
21196         trap cleanup_300n RETURN EXIT
21197         mkdir -p $DIR/$tdir
21198         chmod 777 $DIR/$tdir
21199         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21200                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21201                 error "create striped dir succeeds with gid=0"
21202
21203         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21204         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21205                 error "create striped dir fails with gid=-1"
21206
21207         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21208         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21209                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21210                 error "set default striped dir succeeds with gid=0"
21211
21212
21213         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21214         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21215                 error "set default striped dir fails with gid=-1"
21216
21217
21218         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21219         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21220                                         error "create test_dir fails"
21221         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21222                                         error "create test_dir1 fails"
21223         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21224                                         error "create test_dir2 fails"
21225         cleanup_300n
21226 }
21227 run_test 300n "non-root user to create dir under striped dir with default EA"
21228
21229 test_300o() {
21230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21231         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21232         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21233                 skip "Need MDS version at least 2.7.55"
21234
21235         local numfree1
21236         local numfree2
21237
21238         mkdir -p $DIR/$tdir
21239
21240         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21241         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21242         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21243                 skip "not enough free inodes $numfree1 $numfree2"
21244         fi
21245
21246         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21247         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21248         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21249                 skip "not enough free space $numfree1 $numfree2"
21250         fi
21251
21252         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21253                 error "setdirstripe fails"
21254
21255         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21256                 error "create dirs fails"
21257
21258         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21259         ls $DIR/$tdir/striped_dir > /dev/null ||
21260                 error "ls striped dir fails"
21261         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21262                 error "unlink big striped dir fails"
21263 }
21264 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21265
21266 test_300p() {
21267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21268         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21269         remote_mds_nodsh && skip "remote MDS with nodsh"
21270
21271         mkdir -p $DIR/$tdir
21272
21273         #define OBD_FAIL_OUT_ENOSPC     0x1704
21274         do_facet mds2 lctl set_param fail_loc=0x80001704
21275         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
21276                  && error "create striped directory should fail"
21277
21278         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
21279
21280         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
21281         true
21282 }
21283 run_test 300p "create striped directory without space"
21284
21285 test_300q() {
21286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21287         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21288
21289         local fd=$(free_fd)
21290         local cmd="exec $fd<$tdir"
21291         cd $DIR
21292         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
21293         eval $cmd
21294         cmd="exec $fd<&-"
21295         trap "eval $cmd" EXIT
21296         cd $tdir || error "cd $tdir fails"
21297         rmdir  ../$tdir || error "rmdir $tdir fails"
21298         mkdir local_dir && error "create dir succeeds"
21299         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
21300         eval $cmd
21301         return 0
21302 }
21303 run_test 300q "create remote directory under orphan directory"
21304
21305 test_300r() {
21306         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21307                 skip "Need MDS version at least 2.7.55" && return
21308         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21309
21310         mkdir $DIR/$tdir
21311
21312         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
21313                 error "set striped dir error"
21314
21315         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21316                 error "getstripeddir fails"
21317
21318         local stripe_count
21319         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
21320                       awk '/lmv_stripe_count:/ { print $2 }')
21321
21322         [ $MDSCOUNT -ne $stripe_count ] &&
21323                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
21324
21325         rm -rf $DIR/$tdir/striped_dir ||
21326                 error "unlink striped dir fails"
21327 }
21328 run_test 300r "test -1 striped directory"
21329
21330 prepare_remote_file() {
21331         mkdir $DIR/$tdir/src_dir ||
21332                 error "create remote source failed"
21333
21334         cp /etc/hosts $DIR/$tdir/src_dir/a ||
21335                  error "cp to remote source failed"
21336         touch $DIR/$tdir/src_dir/a
21337
21338         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
21339                 error "create remote target dir failed"
21340
21341         touch $DIR/$tdir/tgt_dir/b
21342
21343         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
21344                 error "rename dir cross MDT failed!"
21345
21346         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
21347                 error "src_child still exists after rename"
21348
21349         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
21350                 error "missing file(a) after rename"
21351
21352         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
21353                 error "diff after rename"
21354 }
21355
21356 test_310a() {
21357         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21359
21360         local remote_file=$DIR/$tdir/tgt_dir/b
21361
21362         mkdir -p $DIR/$tdir
21363
21364         prepare_remote_file || error "prepare remote file failed"
21365
21366         #open-unlink file
21367         $OPENUNLINK $remote_file $remote_file ||
21368                 error "openunlink $remote_file failed"
21369         $CHECKSTAT -a $remote_file || error "$remote_file exists"
21370 }
21371 run_test 310a "open unlink remote file"
21372
21373 test_310b() {
21374         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21376
21377         local remote_file=$DIR/$tdir/tgt_dir/b
21378
21379         mkdir -p $DIR/$tdir
21380
21381         prepare_remote_file || error "prepare remote file failed"
21382
21383         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21384         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
21385         $CHECKSTAT -t file $remote_file || error "check file failed"
21386 }
21387 run_test 310b "unlink remote file with multiple links while open"
21388
21389 test_310c() {
21390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21391         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
21392
21393         local remote_file=$DIR/$tdir/tgt_dir/b
21394
21395         mkdir -p $DIR/$tdir
21396
21397         prepare_remote_file || error "prepare remote file failed"
21398
21399         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21400         multiop_bg_pause $remote_file O_uc ||
21401                         error "mulitop failed for remote file"
21402         MULTIPID=$!
21403         $MULTIOP $DIR/$tfile Ouc
21404         kill -USR1 $MULTIPID
21405         wait $MULTIPID
21406 }
21407 run_test 310c "open-unlink remote file with multiple links"
21408
21409 #LU-4825
21410 test_311() {
21411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21412         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21413         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
21414                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
21415         remote_mds_nodsh && skip "remote MDS with nodsh"
21416
21417         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21418         local mdts=$(comma_list $(mdts_nodes))
21419
21420         mkdir -p $DIR/$tdir
21421         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21422         createmany -o $DIR/$tdir/$tfile. 1000
21423
21424         # statfs data is not real time, let's just calculate it
21425         old_iused=$((old_iused + 1000))
21426
21427         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21428                         osp.*OST0000*MDT0000.create_count")
21429         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21430                                 osp.*OST0000*MDT0000.max_create_count")
21431         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
21432
21433         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
21434         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
21435         [ $index -ne 0 ] || error "$tfile stripe index is 0"
21436
21437         unlinkmany $DIR/$tdir/$tfile. 1000
21438
21439         do_nodes $mdts "$LCTL set_param -n \
21440                         osp.*OST0000*.max_create_count=$max_count"
21441         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
21442                 do_nodes $mdts "$LCTL set_param -n \
21443                                 osp.*OST0000*.create_count=$count"
21444         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
21445                         grep "=0" && error "create_count is zero"
21446
21447         local new_iused
21448         for i in $(seq 120); do
21449                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21450                 # system may be too busy to destroy all objs in time, use
21451                 # a somewhat small value to not fail autotest
21452                 [ $((old_iused - new_iused)) -gt 400 ] && break
21453                 sleep 1
21454         done
21455
21456         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
21457         [ $((old_iused - new_iused)) -gt 400 ] ||
21458                 error "objs not destroyed after unlink"
21459 }
21460 run_test 311 "disable OSP precreate, and unlink should destroy objs"
21461
21462 zfs_oid_to_objid()
21463 {
21464         local ost=$1
21465         local objid=$2
21466
21467         local vdevdir=$(dirname $(facet_vdevice $ost))
21468         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
21469         local zfs_zapid=$(do_facet $ost $cmd |
21470                           grep -w "/O/0/d$((objid%32))" -C 5 |
21471                           awk '/Object/{getline; print $1}')
21472         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
21473                           awk "/$objid = /"'{printf $3}')
21474
21475         echo $zfs_objid
21476 }
21477
21478 zfs_object_blksz() {
21479         local ost=$1
21480         local objid=$2
21481
21482         local vdevdir=$(dirname $(facet_vdevice $ost))
21483         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
21484         local blksz=$(do_facet $ost $cmd $objid |
21485                       awk '/dblk/{getline; printf $4}')
21486
21487         case "${blksz: -1}" in
21488                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
21489                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
21490                 *) ;;
21491         esac
21492
21493         echo $blksz
21494 }
21495
21496 test_312() { # LU-4856
21497         remote_ost_nodsh && skip "remote OST with nodsh"
21498         [ "$ost1_FSTYPE" = "zfs" ] ||
21499                 skip_env "the test only applies to zfs"
21500
21501         local max_blksz=$(do_facet ost1 \
21502                           $ZFS get -p recordsize $(facet_device ost1) |
21503                           awk '!/VALUE/{print $3}')
21504
21505         # to make life a little bit easier
21506         $LFS mkdir -c 1 -i 0 $DIR/$tdir
21507         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21508
21509         local tf=$DIR/$tdir/$tfile
21510         touch $tf
21511         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21512
21513         # Get ZFS object id
21514         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21515         # block size change by sequential overwrite
21516         local bs
21517
21518         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
21519                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
21520
21521                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
21522                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
21523         done
21524         rm -f $tf
21525
21526         # block size change by sequential append write
21527         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
21528         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21529         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21530         local count
21531
21532         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
21533                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
21534                         oflag=sync conv=notrunc
21535
21536                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
21537                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
21538                         error "blksz error, actual $blksz, " \
21539                                 "expected: 2 * $count * $PAGE_SIZE"
21540         done
21541         rm -f $tf
21542
21543         # random write
21544         touch $tf
21545         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21546         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21547
21548         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
21549         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21550         [ $blksz -eq $PAGE_SIZE ] ||
21551                 error "blksz error: $blksz, expected: $PAGE_SIZE"
21552
21553         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
21554         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21555         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
21556
21557         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
21558         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21559         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
21560 }
21561 run_test 312 "make sure ZFS adjusts its block size by write pattern"
21562
21563 test_313() {
21564         remote_ost_nodsh && skip "remote OST with nodsh"
21565
21566         local file=$DIR/$tfile
21567
21568         rm -f $file
21569         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
21570
21571         # define OBD_FAIL_TGT_RCVD_EIO           0x720
21572         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21573         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
21574                 error "write should failed"
21575         do_facet ost1 "$LCTL set_param fail_loc=0"
21576         rm -f $file
21577 }
21578 run_test 313 "io should fail after last_rcvd update fail"
21579
21580 test_314() {
21581         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21582
21583         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
21584         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21585         rm -f $DIR/$tfile
21586         wait_delete_completed
21587         do_facet ost1 "$LCTL set_param fail_loc=0"
21588 }
21589 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
21590
21591 test_315() { # LU-618
21592         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
21593
21594         local file=$DIR/$tfile
21595         rm -f $file
21596
21597         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
21598                 error "multiop file write failed"
21599         $MULTIOP $file oO_RDONLY:r4063232_c &
21600         PID=$!
21601
21602         sleep 2
21603
21604         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
21605         kill -USR1 $PID
21606
21607         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
21608         rm -f $file
21609 }
21610 run_test 315 "read should be accounted"
21611
21612 test_316() {
21613         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21614         large_xattr_enabled || skip_env "ea_inode feature disabled"
21615
21616         rm -rf $DIR/$tdir/d
21617         mkdir -p $DIR/$tdir/d
21618         chown nobody $DIR/$tdir/d
21619         touch $DIR/$tdir/d/file
21620
21621         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
21622 }
21623 run_test 316 "lfs mv"
21624
21625 test_317() {
21626         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
21627                 skip "Need MDS version at least 2.11.53"
21628         if [ "$ost1_FSTYPE" == "zfs" ]; then
21629                 skip "LU-10370: no implementation for ZFS"
21630         fi
21631
21632         local trunc_sz
21633         local grant_blk_size
21634
21635         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
21636                         awk '/grant_block_size:/ { print $2; exit; }')
21637         #
21638         # Create File of size 5M. Truncate it to below size's and verify
21639         # blocks count.
21640         #
21641         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
21642                 error "Create file $DIR/$tfile failed"
21643         stack_trap "rm -f $DIR/$tfile" EXIT
21644
21645         for trunc_sz in 2097152 4097 4000 509 0; do
21646                 $TRUNCATE $DIR/$tfile $trunc_sz ||
21647                         error "truncate $tfile to $trunc_sz failed"
21648                 local sz=$(stat --format=%s $DIR/$tfile)
21649                 local blk=$(stat --format=%b $DIR/$tfile)
21650                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
21651                                      grant_blk_size) * 8))
21652
21653                 if [[ $blk -ne $trunc_blk ]]; then
21654                         $(which stat) $DIR/$tfile
21655                         error "Expected Block $trunc_blk got $blk for $tfile"
21656                 fi
21657
21658                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21659                         error "Expected Size $trunc_sz got $sz for $tfile"
21660         done
21661
21662         #
21663         # sparse file test
21664         # Create file with a hole and write actual two blocks. Block count
21665         # must be 16.
21666         #
21667         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
21668                 conv=fsync || error "Create file : $DIR/$tfile"
21669
21670         # Calculate the final truncate size.
21671         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
21672
21673         #
21674         # truncate to size $trunc_sz bytes. Strip the last block
21675         # The block count must drop to 8
21676         #
21677         $TRUNCATE $DIR/$tfile $trunc_sz ||
21678                 error "truncate $tfile to $trunc_sz failed"
21679
21680         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
21681         sz=$(stat --format=%s $DIR/$tfile)
21682         blk=$(stat --format=%b $DIR/$tfile)
21683
21684         if [[ $blk -ne $trunc_bsz ]]; then
21685                 $(which stat) $DIR/$tfile
21686                 error "Expected Block $trunc_bsz got $blk for $tfile"
21687         fi
21688
21689         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21690                 error "Expected Size $trunc_sz got $sz for $tfile"
21691 }
21692 run_test 317 "Verify blocks get correctly update after truncate"
21693
21694 test_318() {
21695         local old_max_active=$($LCTL get_param -n \
21696                             llite.*.max_read_ahead_async_active 2>/dev/null)
21697
21698         $LCTL set_param llite.*.max_read_ahead_async_active=256
21699         local max_active=$($LCTL get_param -n \
21700                            llite.*.max_read_ahead_async_active 2>/dev/null)
21701         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
21702
21703         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
21704                 error "set max_read_ahead_async_active should succeed"
21705
21706         $LCTL set_param llite.*.max_read_ahead_async_active=512
21707         max_active=$($LCTL get_param -n \
21708                      llite.*.max_read_ahead_async_active 2>/dev/null)
21709         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
21710
21711         # restore @max_active
21712         [ $old_max_active -ne 0 ] && $LCTL set_param \
21713                 llite.*.max_read_ahead_async_active=$old_max_active
21714
21715         local old_threshold=$($LCTL get_param -n \
21716                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21717         local max_per_file_mb=$($LCTL get_param -n \
21718                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
21719
21720         local invalid=$(($max_per_file_mb + 1))
21721         $LCTL set_param \
21722                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
21723                         && error "set $invalid should fail"
21724
21725         local valid=$(($invalid - 1))
21726         $LCTL set_param \
21727                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
21728                         error "set $valid should succeed"
21729         local threshold=$($LCTL get_param -n \
21730                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21731         [ $threshold -eq $valid ] || error \
21732                 "expect threshold $valid got $threshold"
21733         $LCTL set_param \
21734                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
21735 }
21736 run_test 318 "Verify async readahead tunables"
21737
21738 test_319() {
21739         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
21740
21741         local before=$(date +%s)
21742         local evict
21743         local mdir=$DIR/$tdir
21744         local file=$mdir/xxx
21745
21746         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
21747         touch $file
21748
21749 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
21750         $LCTL set_param fail_val=5 fail_loc=0x8000032c
21751         $LFS mv -m1 $file &
21752
21753         sleep 1
21754         dd if=$file of=/dev/null
21755         wait
21756         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
21757           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
21758
21759         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
21760 }
21761 run_test 319 "lost lease lock on migrate error"
21762
21763 test_398a() { # LU-4198
21764         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21765         $LCTL set_param ldlm.namespaces.*.lru_size=clear
21766
21767         # request a new lock on client
21768         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21769
21770         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21771         local lock_count=$($LCTL get_param -n \
21772                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21773         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
21774
21775         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
21776
21777         # no lock cached, should use lockless IO and not enqueue new lock
21778         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21779         lock_count=$($LCTL get_param -n \
21780                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21781         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
21782 }
21783 run_test 398a "direct IO should cancel lock otherwise lockless"
21784
21785 test_398b() { # LU-4198
21786         which fio || skip_env "no fio installed"
21787         $LFS setstripe -c -1 $DIR/$tfile
21788
21789         local size=12
21790         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
21791
21792         local njobs=4
21793         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
21794         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
21795                 --numjobs=$njobs --fallocate=none \
21796                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21797                 --filename=$DIR/$tfile &
21798         bg_pid=$!
21799
21800         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
21801         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
21802                 --numjobs=$njobs --fallocate=none \
21803                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21804                 --filename=$DIR/$tfile || true
21805         wait $bg_pid
21806
21807         rm -rf $DIR/$tfile
21808 }
21809 run_test 398b "DIO and buffer IO race"
21810
21811 test_398c() { # LU-4198
21812         which fio || skip_env "no fio installed"
21813
21814         saved_debug=$($LCTL get_param -n debug)
21815         $LCTL set_param debug=0
21816
21817         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
21818         ((size /= 1024)) # by megabytes
21819         ((size /= 2)) # write half of the OST at most
21820         [ $size -gt 40 ] && size=40 #reduce test time anyway
21821
21822         $LFS setstripe -c 1 $DIR/$tfile
21823
21824         # it seems like ldiskfs reserves more space than necessary if the
21825         # writing blocks are not mapped, so it extends the file firstly
21826         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
21827         cancel_lru_locks osc
21828
21829         # clear and verify rpc_stats later
21830         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
21831
21832         local njobs=4
21833         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
21834         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
21835                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
21836                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21837                 --filename=$DIR/$tfile
21838         [ $? -eq 0 ] || error "fio write error"
21839
21840         [ $($LCTL get_param -n \
21841          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
21842                 error "Locks were requested while doing AIO"
21843
21844         # get the percentage of 1-page I/O
21845         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
21846                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
21847                 awk '{print $7}')
21848         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
21849
21850         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
21851         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
21852                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
21853                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21854                 --filename=$DIR/$tfile
21855         [ $? -eq 0 ] || error "fio mixed read write error"
21856
21857         echo "AIO with large block size ${size}M"
21858         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
21859                 --numjobs=1 --fallocate=none --ioengine=libaio \
21860                 --iodepth=16 --allow_file_create=0 --size=${size}M \
21861                 --filename=$DIR/$tfile
21862         [ $? -eq 0 ] || error "fio large block size failed"
21863
21864         rm -rf $DIR/$tfile
21865         $LCTL set_param debug="$saved_debug"
21866 }
21867 run_test 398c "run fio to test AIO"
21868
21869 test_398d() { #  LU-13846
21870         test -f aiocp || skip_env "no aiocp installed"
21871         local aio_file=$DIR/aio_file
21872
21873         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
21874
21875         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
21876         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
21877
21878         diff $DIR/$tfile $aio_file || "file diff after aiocp"
21879         rm -rf $DIR/$tfile $aio_file
21880 }
21881 run_test 398d "run aiocp to verify block size > stripe size"
21882
21883 test_fake_rw() {
21884         local read_write=$1
21885         if [ "$read_write" = "write" ]; then
21886                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
21887         elif [ "$read_write" = "read" ]; then
21888                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
21889         else
21890                 error "argument error"
21891         fi
21892
21893         # turn off debug for performance testing
21894         local saved_debug=$($LCTL get_param -n debug)
21895         $LCTL set_param debug=0
21896
21897         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21898
21899         # get ost1 size - $FSNAME-OST0000
21900         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
21901         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
21902         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
21903
21904         if [ "$read_write" = "read" ]; then
21905                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
21906         fi
21907
21908         local start_time=$(date +%s.%N)
21909         $dd_cmd bs=1M count=$blocks oflag=sync ||
21910                 error "real dd $read_write error"
21911         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
21912
21913         if [ "$read_write" = "write" ]; then
21914                 rm -f $DIR/$tfile
21915         fi
21916
21917         # define OBD_FAIL_OST_FAKE_RW           0x238
21918         do_facet ost1 $LCTL set_param fail_loc=0x238
21919
21920         local start_time=$(date +%s.%N)
21921         $dd_cmd bs=1M count=$blocks oflag=sync ||
21922                 error "fake dd $read_write error"
21923         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
21924
21925         if [ "$read_write" = "write" ]; then
21926                 # verify file size
21927                 cancel_lru_locks osc
21928                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
21929                         error "$tfile size not $blocks MB"
21930         fi
21931         do_facet ost1 $LCTL set_param fail_loc=0
21932
21933         echo "fake $read_write $duration_fake vs. normal $read_write" \
21934                 "$duration in seconds"
21935         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
21936                 error_not_in_vm "fake write is slower"
21937
21938         $LCTL set_param -n debug="$saved_debug"
21939         rm -f $DIR/$tfile
21940 }
21941 test_399a() { # LU-7655 for OST fake write
21942         remote_ost_nodsh && skip "remote OST with nodsh"
21943
21944         test_fake_rw write
21945 }
21946 run_test 399a "fake write should not be slower than normal write"
21947
21948 test_399b() { # LU-8726 for OST fake read
21949         remote_ost_nodsh && skip "remote OST with nodsh"
21950         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
21951                 skip_env "ldiskfs only test"
21952         fi
21953
21954         test_fake_rw read
21955 }
21956 run_test 399b "fake read should not be slower than normal read"
21957
21958 test_400a() { # LU-1606, was conf-sanity test_74
21959         if ! which $CC > /dev/null 2>&1; then
21960                 skip_env "$CC is not installed"
21961         fi
21962
21963         local extra_flags=''
21964         local out=$TMP/$tfile
21965         local prefix=/usr/include/lustre
21966         local prog
21967
21968         # Oleg removes c files in his test rig so test if any c files exist
21969         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
21970                 skip_env "Needed c test files are missing"
21971
21972         if ! [[ -d $prefix ]]; then
21973                 # Assume we're running in tree and fixup the include path.
21974                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
21975                 extra_flags+=" -L$LUSTRE/utils/.lib"
21976         fi
21977
21978         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
21979                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
21980                         error "client api broken"
21981         done
21982         rm -f $out
21983 }
21984 run_test 400a "Lustre client api program can compile and link"
21985
21986 test_400b() { # LU-1606, LU-5011
21987         local header
21988         local out=$TMP/$tfile
21989         local prefix=/usr/include/linux/lustre
21990
21991         # We use a hard coded prefix so that this test will not fail
21992         # when run in tree. There are headers in lustre/include/lustre/
21993         # that are not packaged (like lustre_idl.h) and have more
21994         # complicated include dependencies (like config.h and lnet/types.h).
21995         # Since this test about correct packaging we just skip them when
21996         # they don't exist (see below) rather than try to fixup cppflags.
21997
21998         if ! which $CC > /dev/null 2>&1; then
21999                 skip_env "$CC is not installed"
22000         fi
22001
22002         for header in $prefix/*.h; do
22003                 if ! [[ -f "$header" ]]; then
22004                         continue
22005                 fi
22006
22007                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22008                         continue # lustre_ioctl.h is internal header
22009                 fi
22010
22011                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22012                         error "cannot compile '$header'"
22013         done
22014         rm -f $out
22015 }
22016 run_test 400b "packaged headers can be compiled"
22017
22018 test_401a() { #LU-7437
22019         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22020         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22021
22022         #count the number of parameters by "list_param -R"
22023         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22024         #count the number of parameters by listing proc files
22025         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22026         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22027         echo "proc_dirs='$proc_dirs'"
22028         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22029         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22030                       sort -u | wc -l)
22031
22032         [ $params -eq $procs ] ||
22033                 error "found $params parameters vs. $procs proc files"
22034
22035         # test the list_param -D option only returns directories
22036         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22037         #count the number of parameters by listing proc directories
22038         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22039                 sort -u | wc -l)
22040
22041         [ $params -eq $procs ] ||
22042                 error "found $params parameters vs. $procs proc files"
22043 }
22044 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22045
22046 test_401b() {
22047         local save=$($LCTL get_param -n jobid_var)
22048         local tmp=testing
22049
22050         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
22051                 error "no error returned when setting bad parameters"
22052
22053         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
22054         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22055
22056         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
22057         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
22058         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22059 }
22060 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22061
22062 test_401c() {
22063         local jobid_var_old=$($LCTL get_param -n jobid_var)
22064         local jobid_var_new
22065
22066         $LCTL set_param jobid_var= &&
22067                 error "no error returned for 'set_param a='"
22068
22069         jobid_var_new=$($LCTL get_param -n jobid_var)
22070         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22071                 error "jobid_var was changed by setting without value"
22072
22073         $LCTL set_param jobid_var &&
22074                 error "no error returned for 'set_param a'"
22075
22076         jobid_var_new=$($LCTL get_param -n jobid_var)
22077         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22078                 error "jobid_var was changed by setting without value"
22079 }
22080 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22081
22082 test_401d() {
22083         local jobid_var_old=$($LCTL get_param -n jobid_var)
22084         local jobid_var_new
22085         local new_value="foo=bar"
22086
22087         $LCTL set_param jobid_var=$new_value ||
22088                 error "'set_param a=b' did not accept a value containing '='"
22089
22090         jobid_var_new=$($LCTL get_param -n jobid_var)
22091         [[ "$jobid_var_new" == "$new_value" ]] ||
22092                 error "'set_param a=b' failed on a value containing '='"
22093
22094         # Reset the jobid_var to test the other format
22095         $LCTL set_param jobid_var=$jobid_var_old
22096         jobid_var_new=$($LCTL get_param -n jobid_var)
22097         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22098                 error "failed to reset jobid_var"
22099
22100         $LCTL set_param jobid_var $new_value ||
22101                 error "'set_param a b' did not accept a value containing '='"
22102
22103         jobid_var_new=$($LCTL get_param -n jobid_var)
22104         [[ "$jobid_var_new" == "$new_value" ]] ||
22105                 error "'set_param a b' failed on a value containing '='"
22106
22107         $LCTL set_param jobid_var $jobid_var_old
22108         jobid_var_new=$($LCTL get_param -n jobid_var)
22109         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22110                 error "failed to reset jobid_var"
22111 }
22112 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22113
22114 test_402() {
22115         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22116         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22117                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22118         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22119                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22120                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22121         remote_mds_nodsh && skip "remote MDS with nodsh"
22122
22123         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22124 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22125         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22126         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22127                 echo "Touch failed - OK"
22128 }
22129 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22130
22131 test_403() {
22132         local file1=$DIR/$tfile.1
22133         local file2=$DIR/$tfile.2
22134         local tfile=$TMP/$tfile
22135
22136         rm -f $file1 $file2 $tfile
22137
22138         touch $file1
22139         ln $file1 $file2
22140
22141         # 30 sec OBD_TIMEOUT in ll_getattr()
22142         # right before populating st_nlink
22143         $LCTL set_param fail_loc=0x80001409
22144         stat -c %h $file1 > $tfile &
22145
22146         # create an alias, drop all locks and reclaim the dentry
22147         < $file2
22148         cancel_lru_locks mdc
22149         cancel_lru_locks osc
22150         sysctl -w vm.drop_caches=2
22151
22152         wait
22153
22154         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
22155
22156         rm -f $tfile $file1 $file2
22157 }
22158 run_test 403 "i_nlink should not drop to zero due to aliasing"
22159
22160 test_404() { # LU-6601
22161         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
22162                 skip "Need server version newer than 2.8.52"
22163         remote_mds_nodsh && skip "remote MDS with nodsh"
22164
22165         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
22166                 awk '/osp .*-osc-MDT/ { print $4}')
22167
22168         local osp
22169         for osp in $mosps; do
22170                 echo "Deactivate: " $osp
22171                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22172                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22173                         awk -vp=$osp '$4 == p { print $2 }')
22174                 [ $stat = IN ] || {
22175                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22176                         error "deactivate error"
22177                 }
22178                 echo "Activate: " $osp
22179                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22180                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22181                         awk -vp=$osp '$4 == p { print $2 }')
22182                 [ $stat = UP ] || {
22183                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22184                         error "activate error"
22185                 }
22186         done
22187 }
22188 run_test 404 "validate manual {de}activated works properly for OSPs"
22189
22190 test_405() {
22191         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22192         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
22193                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
22194                         skip "Layout swap lock is not supported"
22195
22196         check_swap_layouts_support
22197         check_swap_layout_no_dom $DIR
22198
22199         test_mkdir $DIR/$tdir
22200         swap_lock_test -d $DIR/$tdir ||
22201                 error "One layout swap locked test failed"
22202 }
22203 run_test 405 "Various layout swap lock tests"
22204
22205 test_406() {
22206         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22207         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22208         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
22209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22210         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
22211                 skip "Need MDS version at least 2.8.50"
22212
22213         local def_stripe_size=$($LFS getstripe -S $MOUNT)
22214         local test_pool=$TESTNAME
22215
22216         pool_add $test_pool || error "pool_add failed"
22217         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
22218                 error "pool_add_targets failed"
22219
22220         save_layout_restore_at_exit $MOUNT
22221
22222         # parent set default stripe count only, child will stripe from both
22223         # parent and fs default
22224         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
22225                 error "setstripe $MOUNT failed"
22226         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22227         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
22228         for i in $(seq 10); do
22229                 local f=$DIR/$tdir/$tfile.$i
22230                 touch $f || error "touch failed"
22231                 local count=$($LFS getstripe -c $f)
22232                 [ $count -eq $OSTCOUNT ] ||
22233                         error "$f stripe count $count != $OSTCOUNT"
22234                 local offset=$($LFS getstripe -i $f)
22235                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
22236                 local size=$($LFS getstripe -S $f)
22237                 [ $size -eq $((def_stripe_size * 2)) ] ||
22238                         error "$f stripe size $size != $((def_stripe_size * 2))"
22239                 local pool=$($LFS getstripe -p $f)
22240                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
22241         done
22242
22243         # change fs default striping, delete parent default striping, now child
22244         # will stripe from new fs default striping only
22245         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
22246                 error "change $MOUNT default stripe failed"
22247         $LFS setstripe -c 0 $DIR/$tdir ||
22248                 error "delete $tdir default stripe failed"
22249         for i in $(seq 11 20); do
22250                 local f=$DIR/$tdir/$tfile.$i
22251                 touch $f || error "touch $f failed"
22252                 local count=$($LFS getstripe -c $f)
22253                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
22254                 local offset=$($LFS getstripe -i $f)
22255                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
22256                 local size=$($LFS getstripe -S $f)
22257                 [ $size -eq $def_stripe_size ] ||
22258                         error "$f stripe size $size != $def_stripe_size"
22259                 local pool=$($LFS getstripe -p $f)
22260                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
22261         done
22262
22263         unlinkmany $DIR/$tdir/$tfile. 1 20
22264
22265         local f=$DIR/$tdir/$tfile
22266         pool_remove_all_targets $test_pool $f
22267         pool_remove $test_pool $f
22268 }
22269 run_test 406 "DNE support fs default striping"
22270
22271 test_407() {
22272         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22273         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22274                 skip "Need MDS version at least 2.8.55"
22275         remote_mds_nodsh && skip "remote MDS with nodsh"
22276
22277         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
22278                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
22279         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
22280                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
22281         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
22282
22283         #define OBD_FAIL_DT_TXN_STOP    0x2019
22284         for idx in $(seq $MDSCOUNT); do
22285                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
22286         done
22287         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
22288         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
22289                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
22290         true
22291 }
22292 run_test 407 "transaction fail should cause operation fail"
22293
22294 test_408() {
22295         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
22296
22297         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
22298         lctl set_param fail_loc=0x8000040a
22299         # let ll_prepare_partial_page() fail
22300         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
22301
22302         rm -f $DIR/$tfile
22303
22304         # create at least 100 unused inodes so that
22305         # shrink_icache_memory(0) should not return 0
22306         touch $DIR/$tfile-{0..100}
22307         rm -f $DIR/$tfile-{0..100}
22308         sync
22309
22310         echo 2 > /proc/sys/vm/drop_caches
22311 }
22312 run_test 408 "drop_caches should not hang due to page leaks"
22313
22314 test_409()
22315 {
22316         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22317
22318         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
22319         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
22320         touch $DIR/$tdir/guard || error "(2) Fail to create"
22321
22322         local PREFIX=$(str_repeat 'A' 128)
22323         echo "Create 1K hard links start at $(date)"
22324         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22325                 error "(3) Fail to hard link"
22326
22327         echo "Links count should be right although linkEA overflow"
22328         stat $DIR/$tdir/guard || error "(4) Fail to stat"
22329         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
22330         [ $linkcount -eq 1001 ] ||
22331                 error "(5) Unexpected hard links count: $linkcount"
22332
22333         echo "List all links start at $(date)"
22334         ls -l $DIR/$tdir/foo > /dev/null ||
22335                 error "(6) Fail to list $DIR/$tdir/foo"
22336
22337         echo "Unlink hard links start at $(date)"
22338         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22339                 error "(7) Fail to unlink"
22340         echo "Unlink hard links finished at $(date)"
22341 }
22342 run_test 409 "Large amount of cross-MDTs hard links on the same file"
22343
22344 test_410()
22345 {
22346         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
22347                 skip "Need client version at least 2.9.59"
22348
22349         # Create a file, and stat it from the kernel
22350         local testfile=$DIR/$tfile
22351         touch $testfile
22352
22353         local run_id=$RANDOM
22354         local my_ino=$(stat --format "%i" $testfile)
22355
22356         # Try to insert the module. This will always fail as the
22357         # module is designed to not be inserted.
22358         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
22359             &> /dev/null
22360
22361         # Anything but success is a test failure
22362         dmesg | grep -q \
22363             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
22364             error "no inode match"
22365 }
22366 run_test 410 "Test inode number returned from kernel thread"
22367
22368 cleanup_test411_cgroup() {
22369         trap 0
22370         rmdir "$1"
22371 }
22372
22373 test_411() {
22374         local cg_basedir=/sys/fs/cgroup/memory
22375         # LU-9966
22376         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
22377                 skip "no setup for cgroup"
22378
22379         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
22380                 error "test file creation failed"
22381         cancel_lru_locks osc
22382
22383         # Create a very small memory cgroup to force a slab allocation error
22384         local cgdir=$cg_basedir/osc_slab_alloc
22385         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
22386         trap "cleanup_test411_cgroup $cgdir" EXIT
22387         echo 2M > $cgdir/memory.kmem.limit_in_bytes
22388         echo 1M > $cgdir/memory.limit_in_bytes
22389
22390         # Should not LBUG, just be killed by oom-killer
22391         # dd will return 0 even allocation failure in some environment.
22392         # So don't check return value
22393         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
22394         cleanup_test411_cgroup $cgdir
22395
22396         return 0
22397 }
22398 run_test 411 "Slab allocation error with cgroup does not LBUG"
22399
22400 test_412() {
22401         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22402         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
22403                 skip "Need server version at least 2.10.55"
22404         fi
22405
22406         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
22407                 error "mkdir failed"
22408         $LFS getdirstripe $DIR/$tdir
22409         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22410         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
22411                 error "expect $((MDSCOUT - 1)) get $stripe_index"
22412         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
22413         [ $stripe_count -eq 2 ] ||
22414                 error "expect 2 get $stripe_count"
22415 }
22416 run_test 412 "mkdir on specific MDTs"
22417
22418 test_qos_mkdir() {
22419         local mkdir_cmd=$1
22420         local stripe_count=$2
22421         local mdts=$(comma_list $(mdts_nodes))
22422
22423         local testdir
22424         local lmv_qos_prio_free
22425         local lmv_qos_threshold_rr
22426         local lmv_qos_maxage
22427         local lod_qos_prio_free
22428         local lod_qos_threshold_rr
22429         local lod_qos_maxage
22430         local count
22431         local i
22432
22433         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
22434         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
22435         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
22436                 head -n1)
22437         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
22438         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
22439         stack_trap "$LCTL set_param \
22440                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
22441         stack_trap "$LCTL set_param \
22442                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
22443         stack_trap "$LCTL set_param \
22444                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
22445
22446         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
22447                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
22448         lod_qos_prio_free=${lod_qos_prio_free%%%}
22449         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
22450                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
22451         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
22452         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
22453                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
22454         stack_trap "do_nodes $mdts $LCTL set_param \
22455                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
22456         stack_trap "do_nodes $mdts $LCTL set_param \
22457                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
22458                 EXIT
22459         stack_trap "do_nodes $mdts $LCTL set_param \
22460                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
22461
22462         echo
22463         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
22464
22465         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
22466         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
22467
22468         testdir=$DIR/$tdir-s$stripe_count/rr
22469
22470         for i in $(seq $((100 * MDSCOUNT))); do
22471                 eval $mkdir_cmd $testdir/subdir$i ||
22472                         error "$mkdir_cmd subdir$i failed"
22473         done
22474
22475         for i in $(seq $MDSCOUNT); do
22476                 count=$($LFS getdirstripe -i $testdir/* |
22477                                 grep ^$((i - 1))$ | wc -l)
22478                 echo "$count directories created on MDT$((i - 1))"
22479                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
22480
22481                 if [ $stripe_count -gt 1 ]; then
22482                         count=$($LFS getdirstripe $testdir/* |
22483                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22484                         echo "$count stripes created on MDT$((i - 1))"
22485                         # deviation should < 5% of average
22486                         [ $count -lt $((95 * stripe_count)) ] ||
22487                         [ $count -gt $((105 * stripe_count)) ] &&
22488                                 error "stripes are not evenly distributed"
22489                 fi
22490         done
22491
22492         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
22493         do_nodes $mdts $LCTL set_param \
22494                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
22495
22496         echo
22497         echo "Check for uneven MDTs: "
22498
22499         local ffree
22500         local bavail
22501         local max
22502         local min
22503         local max_index
22504         local min_index
22505         local tmp
22506
22507         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
22508         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
22509         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
22510
22511         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22512         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22513         max_index=0
22514         min_index=0
22515         for ((i = 1; i < ${#ffree[@]}; i++)); do
22516                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
22517                 if [ $tmp -gt $max ]; then
22518                         max=$tmp
22519                         max_index=$i
22520                 fi
22521                 if [ $tmp -lt $min ]; then
22522                         min=$tmp
22523                         min_index=$i
22524                 fi
22525         done
22526
22527         [ ${ffree[min_index]} -eq 0 ] &&
22528                 skip "no free files in MDT$min_index"
22529         [ ${ffree[min_index]} -gt 100000000 ] &&
22530                 skip "too much free files in MDT$min_index"
22531
22532         # Check if we need to generate uneven MDTs
22533         local threshold=50
22534         local diff=$(((max - min) * 100 / min))
22535         local value="$(generate_string 1024)"
22536
22537         while [ $diff -lt $threshold ]; do
22538                 # generate uneven MDTs, create till $threshold% diff
22539                 echo -n "weight diff=$diff% must be > $threshold% ..."
22540                 count=$((${ffree[min_index]} / 10))
22541                 # 50 sec per 10000 files in vm
22542                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
22543                         skip "$count files to create"
22544                 echo "Fill MDT$min_index with $count files"
22545                 [ -d $DIR/$tdir-MDT$min_index ] ||
22546                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
22547                         error "mkdir $tdir-MDT$min_index failed"
22548                 for i in $(seq $count); do
22549                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
22550                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
22551                                 error "create f$j_$i failed"
22552                         setfattr -n user.413b -v $value \
22553                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
22554                                 error "setfattr f$j_$i failed"
22555                 done
22556
22557                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
22558                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
22559                 max=$(((${ffree[max_index]} >> 8) * \
22560                         (${bavail[max_index]} * bsize >> 16)))
22561                 min=$(((${ffree[min_index]} >> 8) * \
22562                         (${bavail[min_index]} * bsize >> 16)))
22563                 diff=$(((max - min) * 100 / min))
22564         done
22565
22566         echo "MDT filesfree available: ${ffree[@]}"
22567         echo "MDT blocks available: ${bavail[@]}"
22568         echo "weight diff=$diff%"
22569
22570         echo
22571         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
22572
22573         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
22574         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
22575         # decrease statfs age, so that it can be updated in time
22576         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
22577         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
22578
22579         sleep 1
22580
22581         testdir=$DIR/$tdir-s$stripe_count/qos
22582
22583         for i in $(seq $((100 * MDSCOUNT))); do
22584                 eval $mkdir_cmd $testdir/subdir$i ||
22585                         error "$mkdir_cmd subdir$i failed"
22586         done
22587
22588         for i in $(seq $MDSCOUNT); do
22589                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
22590                         wc -l)
22591                 echo "$count directories created on MDT$((i - 1))"
22592
22593                 if [ $stripe_count -gt 1 ]; then
22594                         count=$($LFS getdirstripe $testdir/* |
22595                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22596                         echo "$count stripes created on MDT$((i - 1))"
22597                 fi
22598         done
22599
22600         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
22601         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
22602
22603         # D-value should > 10% of averge
22604         [ $((max - min)) -lt 10 ] &&
22605                 error "subdirs shouldn't be evenly distributed"
22606
22607         # ditto
22608         if [ $stripe_count -gt 1 ]; then
22609                 max=$($LFS getdirstripe $testdir/* |
22610                         grep -P "^\s+$max_index\t" | wc -l)
22611                 min=$($LFS getdirstripe $testdir/* |
22612                         grep -P "^\s+$min_index\t" | wc -l)
22613                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
22614                         error "stripes shouldn't be evenly distributed"|| true
22615         fi
22616 }
22617
22618 test_413a() {
22619         [ $MDSCOUNT -lt 2 ] &&
22620                 skip "We need at least 2 MDTs for this test"
22621
22622         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22623                 skip "Need server version at least 2.12.52"
22624
22625         local stripe_count
22626
22627         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22628                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22629                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22630                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22631                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
22632         done
22633 }
22634 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
22635
22636 test_413b() {
22637         [ $MDSCOUNT -lt 2 ] &&
22638                 skip "We need at least 2 MDTs for this test"
22639
22640         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22641                 skip "Need server version at least 2.12.52"
22642
22643         local stripe_count
22644
22645         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22646                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22647                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22648                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22649                 $LFS setdirstripe -D -c $stripe_count \
22650                         $DIR/$tdir-s$stripe_count/rr ||
22651                         error "setdirstripe failed"
22652                 $LFS setdirstripe -D -c $stripe_count \
22653                         $DIR/$tdir-s$stripe_count/qos ||
22654                         error "setdirstripe failed"
22655                 test_qos_mkdir "mkdir" $stripe_count
22656         done
22657 }
22658 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
22659
22660 test_414() {
22661 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
22662         $LCTL set_param fail_loc=0x80000521
22663         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
22664         rm -f $DIR/$tfile
22665 }
22666 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
22667
22668 test_415() {
22669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22670         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22671                 skip "Need server version at least 2.11.52"
22672
22673         # LU-11102
22674         local total
22675         local setattr_pid
22676         local start_time
22677         local end_time
22678         local duration
22679
22680         total=500
22681         # this test may be slow on ZFS
22682         [ "$mds1_FSTYPE" == "zfs" ] && total=100
22683
22684         # though this test is designed for striped directory, let's test normal
22685         # directory too since lock is always saved as CoS lock.
22686         test_mkdir $DIR/$tdir || error "mkdir $tdir"
22687         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
22688
22689         (
22690                 while true; do
22691                         touch $DIR/$tdir
22692                 done
22693         ) &
22694         setattr_pid=$!
22695
22696         start_time=$(date +%s)
22697         for i in $(seq $total); do
22698                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
22699                         > /dev/null
22700         done
22701         end_time=$(date +%s)
22702         duration=$((end_time - start_time))
22703
22704         kill -9 $setattr_pid
22705
22706         echo "rename $total files took $duration sec"
22707         [ $duration -lt 100 ] || error "rename took $duration sec"
22708 }
22709 run_test 415 "lock revoke is not missing"
22710
22711 test_416() {
22712         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
22713                 skip "Need server version at least 2.11.55"
22714
22715         # define OBD_FAIL_OSD_TXN_START    0x19a
22716         do_facet mds1 lctl set_param fail_loc=0x19a
22717
22718         lfs mkdir -c $MDSCOUNT $DIR/$tdir
22719
22720         true
22721 }
22722 run_test 416 "transaction start failure won't cause system hung"
22723
22724 cleanup_417() {
22725         trap 0
22726         do_nodes $(comma_list $(mdts_nodes)) \
22727                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
22728         do_nodes $(comma_list $(mdts_nodes)) \
22729                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
22730         do_nodes $(comma_list $(mdts_nodes)) \
22731                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
22732 }
22733
22734 test_417() {
22735         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22736         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
22737                 skip "Need MDS version at least 2.11.56"
22738
22739         trap cleanup_417 RETURN EXIT
22740
22741         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
22742         do_nodes $(comma_list $(mdts_nodes)) \
22743                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
22744         $LFS migrate -m 0 $DIR/$tdir.1 &&
22745                 error "migrate dir $tdir.1 should fail"
22746
22747         do_nodes $(comma_list $(mdts_nodes)) \
22748                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
22749         $LFS mkdir -i 1 $DIR/$tdir.2 &&
22750                 error "create remote dir $tdir.2 should fail"
22751
22752         do_nodes $(comma_list $(mdts_nodes)) \
22753                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
22754         $LFS mkdir -c 2 $DIR/$tdir.3 &&
22755                 error "create striped dir $tdir.3 should fail"
22756         true
22757 }
22758 run_test 417 "disable remote dir, striped dir and dir migration"
22759
22760 # Checks that the outputs of df [-i] and lfs df [-i] match
22761 #
22762 # usage: check_lfs_df <blocks | inodes> <mountpoint>
22763 check_lfs_df() {
22764         local dir=$2
22765         local inodes
22766         local df_out
22767         local lfs_df_out
22768         local count
22769         local passed=false
22770
22771         # blocks or inodes
22772         [ "$1" == "blocks" ] && inodes= || inodes="-i"
22773
22774         for count in {1..100}; do
22775                 cancel_lru_locks
22776                 sync; sleep 0.2
22777
22778                 # read the lines of interest
22779                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
22780                         error "df $inodes $dir | tail -n +2 failed"
22781                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
22782                         error "lfs df $inodes $dir | grep summary: failed"
22783
22784                 # skip first substrings of each output as they are different
22785                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
22786                 # compare the two outputs
22787                 passed=true
22788                 for i in {1..5}; do
22789                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
22790                 done
22791                 $passed && break
22792         done
22793
22794         if ! $passed; then
22795                 df -P $inodes $dir
22796                 echo
22797                 lfs df $inodes $dir
22798                 error "df and lfs df $1 output mismatch: "      \
22799                       "df ${inodes}: ${df_out[*]}, "            \
22800                       "lfs df ${inodes}: ${lfs_df_out[*]}"
22801         fi
22802 }
22803
22804 test_418() {
22805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22806
22807         local dir=$DIR/$tdir
22808         local numfiles=$((RANDOM % 4096 + 2))
22809         local numblocks=$((RANDOM % 256 + 1))
22810
22811         wait_delete_completed
22812         test_mkdir $dir
22813
22814         # check block output
22815         check_lfs_df blocks $dir
22816         # check inode output
22817         check_lfs_df inodes $dir
22818
22819         # create a single file and retest
22820         echo "Creating a single file and testing"
22821         createmany -o $dir/$tfile- 1 &>/dev/null ||
22822                 error "creating 1 file in $dir failed"
22823         check_lfs_df blocks $dir
22824         check_lfs_df inodes $dir
22825
22826         # create a random number of files
22827         echo "Creating $((numfiles - 1)) files and testing"
22828         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
22829                 error "creating $((numfiles - 1)) files in $dir failed"
22830
22831         # write a random number of blocks to the first test file
22832         echo "Writing $numblocks 4K blocks and testing"
22833         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
22834                 count=$numblocks &>/dev/null ||
22835                 error "dd to $dir/${tfile}-0 failed"
22836
22837         # retest
22838         check_lfs_df blocks $dir
22839         check_lfs_df inodes $dir
22840
22841         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
22842                 error "unlinking $numfiles files in $dir failed"
22843 }
22844 run_test 418 "df and lfs df outputs match"
22845
22846 test_419()
22847 {
22848         local dir=$DIR/$tdir
22849
22850         mkdir -p $dir
22851         touch $dir/file
22852
22853         cancel_lru_locks mdc
22854
22855         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
22856         $LCTL set_param fail_loc=0x1410
22857         cat $dir/file
22858         $LCTL set_param fail_loc=0
22859         rm -rf $dir
22860 }
22861 run_test 419 "Verify open file by name doesn't crash kernel"
22862
22863 test_420()
22864 {
22865         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
22866                 skip "Need MDS version at least 2.12.53"
22867
22868         local SAVE_UMASK=$(umask)
22869         local dir=$DIR/$tdir
22870         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
22871
22872         mkdir -p $dir
22873         umask 0000
22874         mkdir -m03777 $dir/testdir
22875         ls -dn $dir/testdir
22876         # Need to remove trailing '.' when SELinux is enabled
22877         local dirperms=$(ls -dn $dir/testdir |
22878                          awk '{ sub(/\.$/, "", $1); print $1}')
22879         [ $dirperms == "drwxrwsrwt" ] ||
22880                 error "incorrect perms on $dir/testdir"
22881
22882         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
22883                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
22884         ls -n $dir/testdir/testfile
22885         local fileperms=$(ls -n $dir/testdir/testfile |
22886                           awk '{ sub(/\.$/, "", $1); print $1}')
22887         [ $fileperms == "-rwxr-xr-x" ] ||
22888                 error "incorrect perms on $dir/testdir/testfile"
22889
22890         umask $SAVE_UMASK
22891 }
22892 run_test 420 "clear SGID bit on non-directories for non-members"
22893
22894 test_421a() {
22895         local cnt
22896         local fid1
22897         local fid2
22898
22899         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22900                 skip "Need MDS version at least 2.12.54"
22901
22902         test_mkdir $DIR/$tdir
22903         createmany -o $DIR/$tdir/f 3
22904         cnt=$(ls -1 $DIR/$tdir | wc -l)
22905         [ $cnt != 3 ] && error "unexpected #files: $cnt"
22906
22907         fid1=$(lfs path2fid $DIR/$tdir/f1)
22908         fid2=$(lfs path2fid $DIR/$tdir/f2)
22909         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
22910
22911         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
22912         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
22913
22914         cnt=$(ls -1 $DIR/$tdir | wc -l)
22915         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
22916
22917         rm -f $DIR/$tdir/f3 || error "can't remove f3"
22918         createmany -o $DIR/$tdir/f 3
22919         cnt=$(ls -1 $DIR/$tdir | wc -l)
22920         [ $cnt != 3 ] && error "unexpected #files: $cnt"
22921
22922         fid1=$(lfs path2fid $DIR/$tdir/f1)
22923         fid2=$(lfs path2fid $DIR/$tdir/f2)
22924         echo "remove using fsname $FSNAME"
22925         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
22926
22927         cnt=$(ls -1 $DIR/$tdir | wc -l)
22928         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
22929 }
22930 run_test 421a "simple rm by fid"
22931
22932 test_421b() {
22933         local cnt
22934         local FID1
22935         local FID2
22936
22937         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22938                 skip "Need MDS version at least 2.12.54"
22939
22940         test_mkdir $DIR/$tdir
22941         createmany -o $DIR/$tdir/f 3
22942         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
22943         MULTIPID=$!
22944
22945         FID1=$(lfs path2fid $DIR/$tdir/f1)
22946         FID2=$(lfs path2fid $DIR/$tdir/f2)
22947         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
22948
22949         kill -USR1 $MULTIPID
22950         wait
22951
22952         cnt=$(ls $DIR/$tdir | wc -l)
22953         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
22954 }
22955 run_test 421b "rm by fid on open file"
22956
22957 test_421c() {
22958         local cnt
22959         local FIDS
22960
22961         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22962                 skip "Need MDS version at least 2.12.54"
22963
22964         test_mkdir $DIR/$tdir
22965         createmany -o $DIR/$tdir/f 3
22966         touch $DIR/$tdir/$tfile
22967         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
22968         cnt=$(ls -1 $DIR/$tdir | wc -l)
22969         [ $cnt != 184 ] && error "unexpected #files: $cnt"
22970
22971         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
22972         $LFS rmfid $DIR $FID1 || error "rmfid failed"
22973
22974         cnt=$(ls $DIR/$tdir | wc -l)
22975         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
22976 }
22977 run_test 421c "rm by fid against hardlinked files"
22978
22979 test_421d() {
22980         local cnt
22981         local FIDS
22982
22983         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22984                 skip "Need MDS version at least 2.12.54"
22985
22986         test_mkdir $DIR/$tdir
22987         createmany -o $DIR/$tdir/f 4097
22988         cnt=$(ls -1 $DIR/$tdir | wc -l)
22989         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
22990
22991         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
22992         $LFS rmfid $DIR $FIDS || error "rmfid failed"
22993
22994         cnt=$(ls $DIR/$tdir | wc -l)
22995         rm -rf $DIR/$tdir
22996         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
22997 }
22998 run_test 421d "rmfid en masse"
22999
23000 test_421e() {
23001         local cnt
23002         local FID
23003
23004         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23005         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23006                 skip "Need MDS version at least 2.12.54"
23007
23008         mkdir -p $DIR/$tdir
23009         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23010         createmany -o $DIR/$tdir/striped_dir/f 512
23011         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23012         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23013
23014         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23015                 sed "s/[/][^:]*://g")
23016         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23017
23018         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23019         rm -rf $DIR/$tdir
23020         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23021 }
23022 run_test 421e "rmfid in DNE"
23023
23024 test_421f() {
23025         local cnt
23026         local FID
23027
23028         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23029                 skip "Need MDS version at least 2.12.54"
23030
23031         test_mkdir $DIR/$tdir
23032         touch $DIR/$tdir/f
23033         cnt=$(ls -1 $DIR/$tdir | wc -l)
23034         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23035
23036         FID=$(lfs path2fid $DIR/$tdir/f)
23037         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23038         # rmfid should fail
23039         cnt=$(ls -1 $DIR/$tdir | wc -l)
23040         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23041
23042         chmod a+rw $DIR/$tdir
23043         ls -la $DIR/$tdir
23044         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23045         # rmfid should fail
23046         cnt=$(ls -1 $DIR/$tdir | wc -l)
23047         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23048
23049         rm -f $DIR/$tdir/f
23050         $RUNAS touch $DIR/$tdir/f
23051         FID=$(lfs path2fid $DIR/$tdir/f)
23052         echo "rmfid as root"
23053         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23054         cnt=$(ls -1 $DIR/$tdir | wc -l)
23055         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23056
23057         rm -f $DIR/$tdir/f
23058         $RUNAS touch $DIR/$tdir/f
23059         cnt=$(ls -1 $DIR/$tdir | wc -l)
23060         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23061         FID=$(lfs path2fid $DIR/$tdir/f)
23062         # rmfid w/o user_fid2path mount option should fail
23063         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23064         cnt=$(ls -1 $DIR/$tdir | wc -l)
23065         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23066
23067         umount_client $MOUNT || error "failed to umount client"
23068         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23069                 error "failed to mount client'"
23070
23071         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23072         # rmfid should succeed
23073         cnt=$(ls -1 $DIR/$tdir | wc -l)
23074         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23075
23076         # rmfid shouldn't allow to remove files due to dir's permission
23077         chmod a+rwx $DIR/$tdir
23078         touch $DIR/$tdir/f
23079         ls -la $DIR/$tdir
23080         FID=$(lfs path2fid $DIR/$tdir/f)
23081         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23082
23083         umount_client $MOUNT || error "failed to umount client"
23084         mount_client $MOUNT "$MOUNT_OPTS" ||
23085                 error "failed to mount client'"
23086
23087 }
23088 run_test 421f "rmfid checks permissions"
23089
23090 test_421g() {
23091         local cnt
23092         local FIDS
23093
23094         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23095         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23096                 skip "Need MDS version at least 2.12.54"
23097
23098         mkdir -p $DIR/$tdir
23099         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23100         createmany -o $DIR/$tdir/striped_dir/f 512
23101         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23102         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23103
23104         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23105                 sed "s/[/][^:]*://g")
23106
23107         rm -f $DIR/$tdir/striped_dir/f1*
23108         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23109         removed=$((512 - cnt))
23110
23111         # few files have been just removed, so we expect
23112         # rmfid to fail on their fids
23113         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23114         [ $removed != $errors ] && error "$errors != $removed"
23115
23116         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23117         rm -rf $DIR/$tdir
23118         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23119 }
23120 run_test 421g "rmfid to return errors properly"
23121
23122 test_422() {
23123         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23124         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23125         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23126         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23127         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23128
23129         local amc=$(at_max_get client)
23130         local amo=$(at_max_get mds1)
23131         local timeout=`lctl get_param -n timeout`
23132
23133         at_max_set 0 client
23134         at_max_set 0 mds1
23135
23136 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23137         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23138                         fail_val=$(((2*timeout + 10)*1000))
23139         touch $DIR/$tdir/d3/file &
23140         sleep 2
23141 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23142         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23143                         fail_val=$((2*timeout + 5))
23144         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23145         local pid=$!
23146         sleep 1
23147         kill -9 $pid
23148         sleep $((2 * timeout))
23149         echo kill $pid
23150         kill -9 $pid
23151         lctl mark touch
23152         touch $DIR/$tdir/d2/file3
23153         touch $DIR/$tdir/d2/file4
23154         touch $DIR/$tdir/d2/file5
23155
23156         wait
23157         at_max_set $amc client
23158         at_max_set $amo mds1
23159
23160         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
23161         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
23162                 error "Watchdog is always throttled"
23163 }
23164 run_test 422 "kill a process with RPC in progress"
23165
23166 stat_test() {
23167     df -h $MOUNT &
23168     df -h $MOUNT &
23169     df -h $MOUNT &
23170     df -h $MOUNT &
23171     df -h $MOUNT &
23172     df -h $MOUNT &
23173 }
23174
23175 test_423() {
23176     local _stats
23177     # ensure statfs cache is expired
23178     sleep 2;
23179
23180     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23181     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23182
23183     return 0
23184 }
23185 run_test 423 "statfs should return a right data"
23186
23187 test_424() {
23188 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
23189         $LCTL set_param fail_loc=0x80000522
23190         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23191         rm -f $DIR/$tfile
23192 }
23193 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
23194
23195 prep_801() {
23196         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23197         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23198                 skip "Need server version at least 2.9.55"
23199
23200         start_full_debug_logging
23201 }
23202
23203 post_801() {
23204         stop_full_debug_logging
23205 }
23206
23207 barrier_stat() {
23208         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23209                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23210                            awk '/The barrier for/ { print $7 }')
23211                 echo $st
23212         else
23213                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
23214                 echo \'$st\'
23215         fi
23216 }
23217
23218 barrier_expired() {
23219         local expired
23220
23221         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23222                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23223                           awk '/will be expired/ { print $7 }')
23224         else
23225                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
23226         fi
23227
23228         echo $expired
23229 }
23230
23231 test_801a() {
23232         prep_801
23233
23234         echo "Start barrier_freeze at: $(date)"
23235         #define OBD_FAIL_BARRIER_DELAY          0x2202
23236         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23237         # Do not reduce barrier time - See LU-11873
23238         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
23239
23240         sleep 2
23241         local b_status=$(barrier_stat)
23242         echo "Got barrier status at: $(date)"
23243         [ "$b_status" = "'freezing_p1'" ] ||
23244                 error "(1) unexpected barrier status $b_status"
23245
23246         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23247         wait
23248         b_status=$(barrier_stat)
23249         [ "$b_status" = "'frozen'" ] ||
23250                 error "(2) unexpected barrier status $b_status"
23251
23252         local expired=$(barrier_expired)
23253         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
23254         sleep $((expired + 3))
23255
23256         b_status=$(barrier_stat)
23257         [ "$b_status" = "'expired'" ] ||
23258                 error "(3) unexpected barrier status $b_status"
23259
23260         # Do not reduce barrier time - See LU-11873
23261         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
23262                 error "(4) fail to freeze barrier"
23263
23264         b_status=$(barrier_stat)
23265         [ "$b_status" = "'frozen'" ] ||
23266                 error "(5) unexpected barrier status $b_status"
23267
23268         echo "Start barrier_thaw at: $(date)"
23269         #define OBD_FAIL_BARRIER_DELAY          0x2202
23270         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23271         do_facet mgs $LCTL barrier_thaw $FSNAME &
23272
23273         sleep 2
23274         b_status=$(barrier_stat)
23275         echo "Got barrier status at: $(date)"
23276         [ "$b_status" = "'thawing'" ] ||
23277                 error "(6) unexpected barrier status $b_status"
23278
23279         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23280         wait
23281         b_status=$(barrier_stat)
23282         [ "$b_status" = "'thawed'" ] ||
23283                 error "(7) unexpected barrier status $b_status"
23284
23285         #define OBD_FAIL_BARRIER_FAILURE        0x2203
23286         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
23287         do_facet mgs $LCTL barrier_freeze $FSNAME
23288
23289         b_status=$(barrier_stat)
23290         [ "$b_status" = "'failed'" ] ||
23291                 error "(8) unexpected barrier status $b_status"
23292
23293         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23294         do_facet mgs $LCTL barrier_thaw $FSNAME
23295
23296         post_801
23297 }
23298 run_test 801a "write barrier user interfaces and stat machine"
23299
23300 test_801b() {
23301         prep_801
23302
23303         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23304         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
23305         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
23306         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
23307         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
23308
23309         cancel_lru_locks mdc
23310
23311         # 180 seconds should be long enough
23312         do_facet mgs $LCTL barrier_freeze $FSNAME 180
23313
23314         local b_status=$(barrier_stat)
23315         [ "$b_status" = "'frozen'" ] ||
23316                 error "(6) unexpected barrier status $b_status"
23317
23318         mkdir $DIR/$tdir/d0/d10 &
23319         mkdir_pid=$!
23320
23321         touch $DIR/$tdir/d1/f13 &
23322         touch_pid=$!
23323
23324         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
23325         ln_pid=$!
23326
23327         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
23328         mv_pid=$!
23329
23330         rm -f $DIR/$tdir/d4/f12 &
23331         rm_pid=$!
23332
23333         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
23334
23335         # To guarantee taht the 'stat' is not blocked
23336         b_status=$(barrier_stat)
23337         [ "$b_status" = "'frozen'" ] ||
23338                 error "(8) unexpected barrier status $b_status"
23339
23340         # let above commands to run at background
23341         sleep 5
23342
23343         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
23344         ps -p $touch_pid || error "(10) touch should be blocked"
23345         ps -p $ln_pid || error "(11) link should be blocked"
23346         ps -p $mv_pid || error "(12) rename should be blocked"
23347         ps -p $rm_pid || error "(13) unlink should be blocked"
23348
23349         b_status=$(barrier_stat)
23350         [ "$b_status" = "'frozen'" ] ||
23351                 error "(14) unexpected barrier status $b_status"
23352
23353         do_facet mgs $LCTL barrier_thaw $FSNAME
23354         b_status=$(barrier_stat)
23355         [ "$b_status" = "'thawed'" ] ||
23356                 error "(15) unexpected barrier status $b_status"
23357
23358         wait $mkdir_pid || error "(16) mkdir should succeed"
23359         wait $touch_pid || error "(17) touch should succeed"
23360         wait $ln_pid || error "(18) link should succeed"
23361         wait $mv_pid || error "(19) rename should succeed"
23362         wait $rm_pid || error "(20) unlink should succeed"
23363
23364         post_801
23365 }
23366 run_test 801b "modification will be blocked by write barrier"
23367
23368 test_801c() {
23369         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23370
23371         prep_801
23372
23373         stop mds2 || error "(1) Fail to stop mds2"
23374
23375         do_facet mgs $LCTL barrier_freeze $FSNAME 30
23376
23377         local b_status=$(barrier_stat)
23378         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
23379                 do_facet mgs $LCTL barrier_thaw $FSNAME
23380                 error "(2) unexpected barrier status $b_status"
23381         }
23382
23383         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23384                 error "(3) Fail to rescan barrier bitmap"
23385
23386         # Do not reduce barrier time - See LU-11873
23387         do_facet mgs $LCTL barrier_freeze $FSNAME 20
23388
23389         b_status=$(barrier_stat)
23390         [ "$b_status" = "'frozen'" ] ||
23391                 error "(4) unexpected barrier status $b_status"
23392
23393         do_facet mgs $LCTL barrier_thaw $FSNAME
23394         b_status=$(barrier_stat)
23395         [ "$b_status" = "'thawed'" ] ||
23396                 error "(5) unexpected barrier status $b_status"
23397
23398         local devname=$(mdsdevname 2)
23399
23400         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
23401
23402         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23403                 error "(7) Fail to rescan barrier bitmap"
23404
23405         post_801
23406 }
23407 run_test 801c "rescan barrier bitmap"
23408
23409 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
23410 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
23411 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
23412 saved_MOUNT_OPTS=$MOUNT_OPTS
23413
23414 cleanup_802a() {
23415         trap 0
23416
23417         stopall
23418         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
23419         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
23420         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
23421         MOUNT_OPTS=$saved_MOUNT_OPTS
23422         setupall
23423 }
23424
23425 test_802a() {
23426         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
23427         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23428         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23429                 skip "Need server version at least 2.9.55"
23430
23431         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
23432
23433         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23434
23435         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23436                 error "(2) Fail to copy"
23437
23438         trap cleanup_802a EXIT
23439
23440         # sync by force before remount as readonly
23441         sync; sync_all_data; sleep 3; sync_all_data
23442
23443         stopall
23444
23445         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
23446         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
23447         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
23448
23449         echo "Mount the server as read only"
23450         setupall server_only || error "(3) Fail to start servers"
23451
23452         echo "Mount client without ro should fail"
23453         mount_client $MOUNT &&
23454                 error "(4) Mount client without 'ro' should fail"
23455
23456         echo "Mount client with ro should succeed"
23457         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
23458         mount_client $MOUNT ||
23459                 error "(5) Mount client with 'ro' should succeed"
23460
23461         echo "Modify should be refused"
23462         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23463
23464         echo "Read should be allowed"
23465         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23466                 error "(7) Read should succeed under ro mode"
23467
23468         cleanup_802a
23469 }
23470 run_test 802a "simulate readonly device"
23471
23472 test_802b() {
23473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23474         remote_mds_nodsh && skip "remote MDS with nodsh"
23475
23476         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
23477                 skip "readonly option not available"
23478
23479         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
23480
23481         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23482                 error "(2) Fail to copy"
23483
23484         # write back all cached data before setting MDT to readonly
23485         cancel_lru_locks
23486         sync_all_data
23487
23488         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
23489         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
23490
23491         echo "Modify should be refused"
23492         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23493
23494         echo "Read should be allowed"
23495         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23496                 error "(7) Read should succeed under ro mode"
23497
23498         # disable readonly
23499         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
23500 }
23501 run_test 802b "be able to set MDTs to readonly"
23502
23503 test_803() {
23504         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23505         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23506                 skip "MDS needs to be newer than 2.10.54"
23507
23508         mkdir -p $DIR/$tdir
23509         # Create some objects on all MDTs to trigger related logs objects
23510         for idx in $(seq $MDSCOUNT); do
23511                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
23512                         $DIR/$tdir/dir${idx} ||
23513                         error "Fail to create $DIR/$tdir/dir${idx}"
23514         done
23515
23516         sync; sleep 3
23517         wait_delete_completed # ensure old test cleanups are finished
23518         echo "before create:"
23519         $LFS df -i $MOUNT
23520         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23521
23522         for i in {1..10}; do
23523                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
23524                         error "Fail to create $DIR/$tdir/foo$i"
23525         done
23526
23527         sync; sleep 3
23528         echo "after create:"
23529         $LFS df -i $MOUNT
23530         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23531
23532         # allow for an llog to be cleaned up during the test
23533         [ $after_used -ge $((before_used + 10 - 1)) ] ||
23534                 error "before ($before_used) + 10 > after ($after_used)"
23535
23536         for i in {1..10}; do
23537                 rm -rf $DIR/$tdir/foo$i ||
23538                         error "Fail to remove $DIR/$tdir/foo$i"
23539         done
23540
23541         sleep 3 # avoid MDT return cached statfs
23542         wait_delete_completed
23543         echo "after unlink:"
23544         $LFS df -i $MOUNT
23545         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23546
23547         # allow for an llog to be created during the test
23548         [ $after_used -le $((before_used + 1)) ] ||
23549                 error "after ($after_used) > before ($before_used) + 1"
23550 }
23551 run_test 803 "verify agent object for remote object"
23552
23553 test_804() {
23554         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23555         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23556                 skip "MDS needs to be newer than 2.10.54"
23557         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
23558
23559         mkdir -p $DIR/$tdir
23560         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
23561                 error "Fail to create $DIR/$tdir/dir0"
23562
23563         local fid=$($LFS path2fid $DIR/$tdir/dir0)
23564         local dev=$(mdsdevname 2)
23565
23566         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23567                 grep ${fid} || error "NOT found agent entry for dir0"
23568
23569         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
23570                 error "Fail to create $DIR/$tdir/dir1"
23571
23572         touch $DIR/$tdir/dir1/foo0 ||
23573                 error "Fail to create $DIR/$tdir/dir1/foo0"
23574         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
23575         local rc=0
23576
23577         for idx in $(seq $MDSCOUNT); do
23578                 dev=$(mdsdevname $idx)
23579                 do_facet mds${idx} \
23580                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23581                         grep ${fid} && rc=$idx
23582         done
23583
23584         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
23585                 error "Fail to rename foo0 to foo1"
23586         if [ $rc -eq 0 ]; then
23587                 for idx in $(seq $MDSCOUNT); do
23588                         dev=$(mdsdevname $idx)
23589                         do_facet mds${idx} \
23590                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23591                         grep ${fid} && rc=$idx
23592                 done
23593         fi
23594
23595         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
23596                 error "Fail to rename foo1 to foo2"
23597         if [ $rc -eq 0 ]; then
23598                 for idx in $(seq $MDSCOUNT); do
23599                         dev=$(mdsdevname $idx)
23600                         do_facet mds${idx} \
23601                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23602                         grep ${fid} && rc=$idx
23603                 done
23604         fi
23605
23606         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
23607
23608         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
23609                 error "Fail to link to $DIR/$tdir/dir1/foo2"
23610         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
23611                 error "Fail to rename foo2 to foo0"
23612         unlink $DIR/$tdir/dir1/foo0 ||
23613                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
23614         rm -rf $DIR/$tdir/dir0 ||
23615                 error "Fail to rm $DIR/$tdir/dir0"
23616
23617         for idx in $(seq $MDSCOUNT); do
23618                 dev=$(mdsdevname $idx)
23619                 rc=0
23620
23621                 stop mds${idx}
23622                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
23623                         rc=$?
23624                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
23625                         error "mount mds$idx failed"
23626                 df $MOUNT > /dev/null 2>&1
23627
23628                 # e2fsck should not return error
23629                 [ $rc -eq 0 ] ||
23630                         error "e2fsck detected error on MDT${idx}: rc=$rc"
23631         done
23632 }
23633 run_test 804 "verify agent entry for remote entry"
23634
23635 cleanup_805() {
23636         do_facet $SINGLEMDS zfs set quota=$old $fsset
23637         unlinkmany $DIR/$tdir/f- 1000000
23638         trap 0
23639 }
23640
23641 test_805() {
23642         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
23643         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
23644         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
23645                 skip "netfree not implemented before 0.7"
23646         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
23647                 skip "Need MDS version at least 2.10.57"
23648
23649         local fsset
23650         local freekb
23651         local usedkb
23652         local old
23653         local quota
23654         local pref="osd-zfs.$FSNAME-MDT0000."
23655
23656         # limit available space on MDS dataset to meet nospace issue
23657         # quickly. then ZFS 0.7.2 can use reserved space if asked
23658         # properly (using netfree flag in osd_declare_destroy()
23659         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
23660         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
23661                 gawk '{print $3}')
23662         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
23663         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
23664         let "usedkb=usedkb-freekb"
23665         let "freekb=freekb/2"
23666         if let "freekb > 5000"; then
23667                 let "freekb=5000"
23668         fi
23669         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
23670         trap cleanup_805 EXIT
23671         mkdir $DIR/$tdir
23672         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
23673                 error "Can't set PFL layout"
23674         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
23675         rm -rf $DIR/$tdir || error "not able to remove"
23676         do_facet $SINGLEMDS zfs set quota=$old $fsset
23677         trap 0
23678 }
23679 run_test 805 "ZFS can remove from full fs"
23680
23681 # Size-on-MDS test
23682 check_lsom_data()
23683 {
23684         local file=$1
23685         local size=$($LFS getsom -s $file)
23686         local expect=$(stat -c %s $file)
23687
23688         [[ $size == $expect ]] ||
23689                 error "$file expected size: $expect, got: $size"
23690
23691         local blocks=$($LFS getsom -b $file)
23692         expect=$(stat -c %b $file)
23693         [[ $blocks == $expect ]] ||
23694                 error "$file expected blocks: $expect, got: $blocks"
23695 }
23696
23697 check_lsom_size()
23698 {
23699         local size=$($LFS getsom -s $1)
23700         local expect=$2
23701
23702         [[ $size == $expect ]] ||
23703                 error "$file expected size: $expect, got: $size"
23704 }
23705
23706 test_806() {
23707         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23708                 skip "Need MDS version at least 2.11.52"
23709
23710         local bs=1048576
23711
23712         touch $DIR/$tfile || error "touch $tfile failed"
23713
23714         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23715         save_lustre_params client "llite.*.xattr_cache" > $save
23716         lctl set_param llite.*.xattr_cache=0
23717         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23718
23719         # single-threaded write
23720         echo "Test SOM for single-threaded write"
23721         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
23722                 error "write $tfile failed"
23723         check_lsom_size $DIR/$tfile $bs
23724
23725         local num=32
23726         local size=$(($num * $bs))
23727         local offset=0
23728         local i
23729
23730         echo "Test SOM for single client multi-threaded($num) write"
23731         $TRUNCATE $DIR/$tfile 0
23732         for ((i = 0; i < $num; i++)); do
23733                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23734                 local pids[$i]=$!
23735                 offset=$((offset + $bs))
23736         done
23737         for (( i=0; i < $num; i++ )); do
23738                 wait ${pids[$i]}
23739         done
23740         check_lsom_size $DIR/$tfile $size
23741
23742         $TRUNCATE $DIR/$tfile 0
23743         for ((i = 0; i < $num; i++)); do
23744                 offset=$((offset - $bs))
23745                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23746                 local pids[$i]=$!
23747         done
23748         for (( i=0; i < $num; i++ )); do
23749                 wait ${pids[$i]}
23750         done
23751         check_lsom_size $DIR/$tfile $size
23752
23753         # multi-client writes
23754         num=$(get_node_count ${CLIENTS//,/ })
23755         size=$(($num * $bs))
23756         offset=0
23757         i=0
23758
23759         echo "Test SOM for multi-client ($num) writes"
23760         $TRUNCATE $DIR/$tfile 0
23761         for client in ${CLIENTS//,/ }; do
23762                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23763                 local pids[$i]=$!
23764                 i=$((i + 1))
23765                 offset=$((offset + $bs))
23766         done
23767         for (( i=0; i < $num; i++ )); do
23768                 wait ${pids[$i]}
23769         done
23770         check_lsom_size $DIR/$tfile $offset
23771
23772         i=0
23773         $TRUNCATE $DIR/$tfile 0
23774         for client in ${CLIENTS//,/ }; do
23775                 offset=$((offset - $bs))
23776                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23777                 local pids[$i]=$!
23778                 i=$((i + 1))
23779         done
23780         for (( i=0; i < $num; i++ )); do
23781                 wait ${pids[$i]}
23782         done
23783         check_lsom_size $DIR/$tfile $size
23784
23785         # verify truncate
23786         echo "Test SOM for truncate"
23787         $TRUNCATE $DIR/$tfile 1048576
23788         check_lsom_size $DIR/$tfile 1048576
23789         $TRUNCATE $DIR/$tfile 1234
23790         check_lsom_size $DIR/$tfile 1234
23791
23792         # verify SOM blocks count
23793         echo "Verify SOM block count"
23794         $TRUNCATE $DIR/$tfile 0
23795         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
23796                 error "failed to write file $tfile"
23797         check_lsom_data $DIR/$tfile
23798 }
23799 run_test 806 "Verify Lazy Size on MDS"
23800
23801 test_807() {
23802         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
23803         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23804                 skip "Need MDS version at least 2.11.52"
23805
23806         # Registration step
23807         changelog_register || error "changelog_register failed"
23808         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
23809         changelog_users $SINGLEMDS | grep -q $cl_user ||
23810                 error "User $cl_user not found in changelog_users"
23811
23812         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23813         save_lustre_params client "llite.*.xattr_cache" > $save
23814         lctl set_param llite.*.xattr_cache=0
23815         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23816
23817         rm -rf $DIR/$tdir || error "rm $tdir failed"
23818         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
23819         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
23820         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
23821         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
23822                 error "truncate $tdir/trunc failed"
23823
23824         local bs=1048576
23825         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
23826                 error "write $tfile failed"
23827
23828         # multi-client wirtes
23829         local num=$(get_node_count ${CLIENTS//,/ })
23830         local offset=0
23831         local i=0
23832
23833         echo "Test SOM for multi-client ($num) writes"
23834         touch $DIR/$tfile || error "touch $tfile failed"
23835         $TRUNCATE $DIR/$tfile 0
23836         for client in ${CLIENTS//,/ }; do
23837                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23838                 local pids[$i]=$!
23839                 i=$((i + 1))
23840                 offset=$((offset + $bs))
23841         done
23842         for (( i=0; i < $num; i++ )); do
23843                 wait ${pids[$i]}
23844         done
23845
23846         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
23847         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
23848         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
23849         check_lsom_data $DIR/$tdir/trunc
23850         check_lsom_data $DIR/$tdir/single_dd
23851         check_lsom_data $DIR/$tfile
23852
23853         rm -rf $DIR/$tdir
23854         # Deregistration step
23855         changelog_deregister || error "changelog_deregister failed"
23856 }
23857 run_test 807 "verify LSOM syncing tool"
23858
23859 check_som_nologged()
23860 {
23861         local lines=$($LFS changelog $FSNAME-MDT0000 |
23862                 grep 'x=trusted.som' | wc -l)
23863         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
23864 }
23865
23866 test_808() {
23867         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
23868                 skip "Need MDS version at least 2.11.55"
23869
23870         # Registration step
23871         changelog_register || error "changelog_register failed"
23872
23873         touch $DIR/$tfile || error "touch $tfile failed"
23874         check_som_nologged
23875
23876         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
23877                 error "write $tfile failed"
23878         check_som_nologged
23879
23880         $TRUNCATE $DIR/$tfile 1234
23881         check_som_nologged
23882
23883         $TRUNCATE $DIR/$tfile 1048576
23884         check_som_nologged
23885
23886         # Deregistration step
23887         changelog_deregister || error "changelog_deregister failed"
23888 }
23889 run_test 808 "Check trusted.som xattr not logged in Changelogs"
23890
23891 check_som_nodata()
23892 {
23893         $LFS getsom $1
23894         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
23895 }
23896
23897 test_809() {
23898         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
23899                 skip "Need MDS version at least 2.11.56"
23900
23901         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
23902                 error "failed to create DoM-only file $DIR/$tfile"
23903         touch $DIR/$tfile || error "touch $tfile failed"
23904         check_som_nodata $DIR/$tfile
23905
23906         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
23907                 error "write $tfile failed"
23908         check_som_nodata $DIR/$tfile
23909
23910         $TRUNCATE $DIR/$tfile 1234
23911         check_som_nodata $DIR/$tfile
23912
23913         $TRUNCATE $DIR/$tfile 4097
23914         check_som_nodata $DIR/$file
23915 }
23916 run_test 809 "Verify no SOM xattr store for DoM-only files"
23917
23918 test_810() {
23919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23920         $GSS && skip_env "could not run with gss"
23921         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
23922                 skip "OST < 2.12.58 doesn't align checksum"
23923
23924         set_checksums 1
23925         stack_trap "set_checksums $ORIG_CSUM" EXIT
23926         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
23927
23928         local csum
23929         local before
23930         local after
23931         for csum in $CKSUM_TYPES; do
23932                 #define OBD_FAIL_OSC_NO_GRANT   0x411
23933                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
23934                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
23935                         eval set -- $i
23936                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
23937                         before=$(md5sum $DIR/$tfile)
23938                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
23939                         after=$(md5sum $DIR/$tfile)
23940                         [ "$before" == "$after" ] ||
23941                                 error "$csum: $before != $after bs=$1 seek=$2"
23942                 done
23943         done
23944 }
23945 run_test 810 "partial page writes on ZFS (LU-11663)"
23946
23947 test_812a() {
23948         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
23949                 skip "OST < 2.12.51 doesn't support this fail_loc"
23950         [ "$SHARED_KEY" = true ] &&
23951                 skip "OSC connections never go IDLE with Shared-Keys enabled"
23952
23953         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23954         # ensure ost1 is connected
23955         stat $DIR/$tfile >/dev/null || error "can't stat"
23956         wait_osc_import_state client ost1 FULL
23957         # no locks, no reqs to let the connection idle
23958         cancel_lru_locks osc
23959
23960         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
23961 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
23962         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
23963         wait_osc_import_state client ost1 CONNECTING
23964         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
23965
23966         stat $DIR/$tfile >/dev/null || error "can't stat file"
23967 }
23968 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
23969
23970 test_812b() { # LU-12378
23971         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
23972                 skip "OST < 2.12.51 doesn't support this fail_loc"
23973         [ "$SHARED_KEY" = true ] &&
23974                 skip "OSC connections never go IDLE with Shared-Keys enabled"
23975
23976         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
23977         # ensure ost1 is connected
23978         stat $DIR/$tfile >/dev/null || error "can't stat"
23979         wait_osc_import_state client ost1 FULL
23980         # no locks, no reqs to let the connection idle
23981         cancel_lru_locks osc
23982
23983         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
23984 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
23985         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
23986         wait_osc_import_state client ost1 CONNECTING
23987         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
23988
23989         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
23990         wait_osc_import_state client ost1 IDLE
23991 }
23992 run_test 812b "do not drop no resend request for idle connect"
23993
23994 test_813() {
23995         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
23996         [ -z "$file_heat_sav" ] && skip "no file heat support"
23997
23998         local readsample
23999         local writesample
24000         local readbyte
24001         local writebyte
24002         local readsample1
24003         local writesample1
24004         local readbyte1
24005         local writebyte1
24006
24007         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
24008         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
24009
24010         $LCTL set_param -n llite.*.file_heat=1
24011         echo "Turn on file heat"
24012         echo "Period second: $period_second, Decay percentage: $decay_pct"
24013
24014         echo "QQQQ" > $DIR/$tfile
24015         echo "QQQQ" > $DIR/$tfile
24016         echo "QQQQ" > $DIR/$tfile
24017         cat $DIR/$tfile > /dev/null
24018         cat $DIR/$tfile > /dev/null
24019         cat $DIR/$tfile > /dev/null
24020         cat $DIR/$tfile > /dev/null
24021
24022         local out=$($LFS heat_get $DIR/$tfile)
24023
24024         $LFS heat_get $DIR/$tfile
24025         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24026         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24027         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24028         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24029
24030         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
24031         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
24032         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
24033         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
24034
24035         sleep $((period_second + 3))
24036         echo "Sleep $((period_second + 3)) seconds..."
24037         # The recursion formula to calculate the heat of the file f is as
24038         # follow:
24039         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
24040         # Where Hi is the heat value in the period between time points i*I and
24041         # (i+1)*I; Ci is the access count in the period; the symbol P refers
24042         # to the weight of Ci.
24043         out=$($LFS heat_get $DIR/$tfile)
24044         $LFS heat_get $DIR/$tfile
24045         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24046         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24047         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24048         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24049
24050         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
24051                 error "read sample ($readsample) is wrong"
24052         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
24053                 error "write sample ($writesample) is wrong"
24054         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
24055                 error "read bytes ($readbyte) is wrong"
24056         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
24057                 error "write bytes ($writebyte) is wrong"
24058
24059         echo "QQQQ" > $DIR/$tfile
24060         echo "QQQQ" > $DIR/$tfile
24061         echo "QQQQ" > $DIR/$tfile
24062         cat $DIR/$tfile > /dev/null
24063         cat $DIR/$tfile > /dev/null
24064         cat $DIR/$tfile > /dev/null
24065         cat $DIR/$tfile > /dev/null
24066
24067         sleep $((period_second + 3))
24068         echo "Sleep $((period_second + 3)) seconds..."
24069
24070         out=$($LFS heat_get $DIR/$tfile)
24071         $LFS heat_get $DIR/$tfile
24072         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24073         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24074         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24075         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24076
24077         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
24078                 4 * $decay_pct) / 100") -eq 1 ] ||
24079                 error "read sample ($readsample1) is wrong"
24080         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
24081                 3 * $decay_pct) / 100") -eq 1 ] ||
24082                 error "write sample ($writesample1) is wrong"
24083         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
24084                 20 * $decay_pct) / 100") -eq 1 ] ||
24085                 error "read bytes ($readbyte1) is wrong"
24086         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
24087                 15 * $decay_pct) / 100") -eq 1 ] ||
24088                 error "write bytes ($writebyte1) is wrong"
24089
24090         echo "Turn off file heat for the file $DIR/$tfile"
24091         $LFS heat_set -o $DIR/$tfile
24092
24093         echo "QQQQ" > $DIR/$tfile
24094         echo "QQQQ" > $DIR/$tfile
24095         echo "QQQQ" > $DIR/$tfile
24096         cat $DIR/$tfile > /dev/null
24097         cat $DIR/$tfile > /dev/null
24098         cat $DIR/$tfile > /dev/null
24099         cat $DIR/$tfile > /dev/null
24100
24101         out=$($LFS heat_get $DIR/$tfile)
24102         $LFS heat_get $DIR/$tfile
24103         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24104         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24105         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24106         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24107
24108         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24109         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24110         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24111         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24112
24113         echo "Trun on file heat for the file $DIR/$tfile"
24114         $LFS heat_set -O $DIR/$tfile
24115
24116         echo "QQQQ" > $DIR/$tfile
24117         echo "QQQQ" > $DIR/$tfile
24118         echo "QQQQ" > $DIR/$tfile
24119         cat $DIR/$tfile > /dev/null
24120         cat $DIR/$tfile > /dev/null
24121         cat $DIR/$tfile > /dev/null
24122         cat $DIR/$tfile > /dev/null
24123
24124         out=$($LFS heat_get $DIR/$tfile)
24125         $LFS heat_get $DIR/$tfile
24126         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24127         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24128         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24129         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24130
24131         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
24132         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
24133         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
24134         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
24135
24136         $LFS heat_set -c $DIR/$tfile
24137         $LCTL set_param -n llite.*.file_heat=0
24138         echo "Turn off file heat support for the Lustre filesystem"
24139
24140         echo "QQQQ" > $DIR/$tfile
24141         echo "QQQQ" > $DIR/$tfile
24142         echo "QQQQ" > $DIR/$tfile
24143         cat $DIR/$tfile > /dev/null
24144         cat $DIR/$tfile > /dev/null
24145         cat $DIR/$tfile > /dev/null
24146         cat $DIR/$tfile > /dev/null
24147
24148         out=$($LFS heat_get $DIR/$tfile)
24149         $LFS heat_get $DIR/$tfile
24150         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24151         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24152         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24153         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24154
24155         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24156         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24157         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24158         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24159
24160         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
24161         rm -f $DIR/$tfile
24162 }
24163 run_test 813 "File heat verfication"
24164
24165 test_814()
24166 {
24167         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
24168         echo -n y >> $DIR/$tfile
24169         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
24170         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
24171 }
24172 run_test 814 "sparse cp works as expected (LU-12361)"
24173
24174 test_815()
24175 {
24176         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
24177         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
24178 }
24179 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
24180
24181 test_816() {
24182         [ "$SHARED_KEY" = true ] &&
24183                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24184
24185         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24186         # ensure ost1 is connected
24187         stat $DIR/$tfile >/dev/null || error "can't stat"
24188         wait_osc_import_state client ost1 FULL
24189         # no locks, no reqs to let the connection idle
24190         cancel_lru_locks osc
24191         lru_resize_disable osc
24192         local before
24193         local now
24194         before=$($LCTL get_param -n \
24195                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24196
24197         wait_osc_import_state client ost1 IDLE
24198         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
24199         now=$($LCTL get_param -n \
24200               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24201         [ $before == $now ] || error "lru_size changed $before != $now"
24202 }
24203 run_test 816 "do not reset lru_resize on idle reconnect"
24204
24205 cleanup_817() {
24206         umount $tmpdir
24207         exportfs -u localhost:$DIR/nfsexp
24208         rm -rf $DIR/nfsexp
24209 }
24210
24211 test_817() {
24212         systemctl restart nfs-server.service || skip "failed to restart nfsd"
24213
24214         mkdir -p $DIR/nfsexp
24215         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
24216                 error "failed to export nfs"
24217
24218         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
24219         stack_trap cleanup_817 EXIT
24220
24221         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
24222                 error "failed to mount nfs to $tmpdir"
24223
24224         cp /bin/true $tmpdir
24225         $DIR/nfsexp/true || error "failed to execute 'true' command"
24226 }
24227 run_test 817 "nfsd won't cache write lock for exec file"
24228
24229 test_818() {
24230         mkdir $DIR/$tdir
24231         $LFS setstripe -c1 -i0 $DIR/$tfile
24232         $LFS setstripe -c1 -i1 $DIR/$tfile
24233         stop $SINGLEMDS
24234         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
24235         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
24236         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
24237                 error "start $SINGLEMDS failed"
24238         rm -rf $DIR/$tdir
24239 }
24240 run_test 818 "unlink with failed llog"
24241
24242 test_819a() {
24243         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24244         cancel_lru_locks osc
24245         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24246         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24247         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
24248         rm -f $TDIR/$tfile
24249 }
24250 run_test 819a "too big niobuf in read"
24251
24252 test_819b() {
24253         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24254         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24255         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24256         cancel_lru_locks osc
24257         sleep 1
24258         rm -f $TDIR/$tfile
24259 }
24260 run_test 819b "too big niobuf in write"
24261
24262
24263 function test_820_start_ost() {
24264         sleep 5
24265
24266         for num in $(seq $OSTCOUNT); do
24267                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
24268         done
24269 }
24270
24271 test_820() {
24272         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24273
24274         mkdir $DIR/$tdir
24275         umount_client $MOUNT || error "umount failed"
24276         for num in $(seq $OSTCOUNT); do
24277                 stop ost$num
24278         done
24279
24280         # mount client with no active OSTs
24281         # so that the client can't initialize max LOV EA size
24282         # from OSC notifications
24283         mount_client $MOUNT || error "mount failed"
24284         # delay OST starting to keep this 0 max EA size for a while
24285         test_820_start_ost &
24286
24287         # create a directory on MDS2
24288         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
24289                 error "Failed to create directory"
24290         # open intent should update default EA size
24291         # see mdc_update_max_ea_from_body()
24292         # notice this is the very first RPC to MDS2
24293         cp /etc/services $DIR/$tdir/mds2 ||
24294                 error "Failed to copy files to mds$n"
24295 }
24296 run_test 820 "update max EA from open intent"
24297
24298 #
24299 # tests that do cleanup/setup should be run at the end
24300 #
24301
24302 test_900() {
24303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24304         local ls
24305
24306         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
24307         $LCTL set_param fail_loc=0x903
24308
24309         cancel_lru_locks MGC
24310
24311         FAIL_ON_ERROR=true cleanup
24312         FAIL_ON_ERROR=true setup
24313 }
24314 run_test 900 "umount should not race with any mgc requeue thread"
24315
24316 # LUS-6253/LU-11185
24317 test_901() {
24318         local oldc
24319         local newc
24320         local olds
24321         local news
24322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24323
24324         # some get_param have a bug to handle dot in param name
24325         cancel_lru_locks MGC
24326         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24327         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24328         umount_client $MOUNT || error "umount failed"
24329         mount_client $MOUNT || error "mount failed"
24330         cancel_lru_locks MGC
24331         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24332         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24333
24334         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
24335         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
24336
24337         return 0
24338 }
24339 run_test 901 "don't leak a mgc lock on client umount"
24340
24341 # LU-13377
24342 test_902() {
24343         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
24344                 skip "client does not have LU-13377 fix"
24345         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
24346         $LCTL set_param fail_loc=0x1415
24347         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24348         cancel_lru_locks osc
24349         rm -f $DIR/$tfile
24350 }
24351 run_test 902 "test short write doesn't hang lustre"
24352
24353 complete $SECONDS
24354 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
24355 check_and_cleanup_lustre
24356 if [ "$I_MOUNTED" != "yes" ]; then
24357         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
24358 fi
24359 exit_status