Whamcloud - gitweb
41175542d57545a0374a7f581be1f3a1c17541ff
[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
45 ALWAYS_EXCEPT+=" 407     312"
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.12.0 until they are fixed
67 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.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..250}; 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 < 20 )) || 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         # Wait for multiop to exit
4884         wait $pid
4885 }
4886 run_test 43A "execution of file opened for write should return -ETXTBSY"
4887
4888 test_43a() {
4889         test_mkdir $DIR/$tdir
4890         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4891         $DIR/$tdir/sleep 60 &
4892         SLEEP_PID=$!
4893         # Make sure exec of $tdir/sleep wins race with truncate
4894         sleep 1
4895         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4896         kill $SLEEP_PID
4897 }
4898 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4899
4900 test_43b() {
4901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4902
4903         test_mkdir $DIR/$tdir
4904         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4905         $DIR/$tdir/sleep 60 &
4906         SLEEP_PID=$!
4907         # Make sure exec of $tdir/sleep wins race with truncate
4908         sleep 1
4909         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4910         kill $SLEEP_PID
4911 }
4912 run_test 43b "truncate of file being executed should return -ETXTBSY"
4913
4914 test_43c() {
4915         local testdir="$DIR/$tdir"
4916         test_mkdir $testdir
4917         cp $SHELL $testdir/
4918         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4919                 ( cd $testdir && md5sum -c )
4920 }
4921 run_test 43c "md5sum of copy into lustre"
4922
4923 test_44A() { # was test_44
4924         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4925
4926         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4927         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4928 }
4929 run_test 44A "zero length read from a sparse stripe"
4930
4931 test_44a() {
4932         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4933                 awk '{ print $2 }')
4934         [ -z "$nstripe" ] && skip "can't get stripe info"
4935         [[ $nstripe -gt $OSTCOUNT ]] &&
4936                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4937
4938         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4939                 awk '{ print $2 }')
4940         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4941                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4942                         awk '{ print $2 }')
4943         fi
4944
4945         OFFSETS="0 $((stride/2)) $((stride-1))"
4946         for offset in $OFFSETS; do
4947                 for i in $(seq 0 $((nstripe-1))); do
4948                         local GLOBALOFFSETS=""
4949                         # size in Bytes
4950                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4951                         local myfn=$DIR/d44a-$size
4952                         echo "--------writing $myfn at $size"
4953                         ll_sparseness_write $myfn $size ||
4954                                 error "ll_sparseness_write"
4955                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4956                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4957                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4958
4959                         for j in $(seq 0 $((nstripe-1))); do
4960                                 # size in Bytes
4961                                 size=$((((j + $nstripe )*$stride + $offset)))
4962                                 ll_sparseness_write $myfn $size ||
4963                                         error "ll_sparseness_write"
4964                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4965                         done
4966                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4967                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4968                         rm -f $myfn
4969                 done
4970         done
4971 }
4972 run_test 44a "test sparse pwrite ==============================="
4973
4974 dirty_osc_total() {
4975         tot=0
4976         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4977                 tot=$(($tot + $d))
4978         done
4979         echo $tot
4980 }
4981 do_dirty_record() {
4982         before=`dirty_osc_total`
4983         echo executing "\"$*\""
4984         eval $*
4985         after=`dirty_osc_total`
4986         echo before $before, after $after
4987 }
4988 test_45() {
4989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4990
4991         f="$DIR/f45"
4992         # Obtain grants from OST if it supports it
4993         echo blah > ${f}_grant
4994         stop_writeback
4995         sync
4996         do_dirty_record "echo blah > $f"
4997         [[ $before -eq $after ]] && error "write wasn't cached"
4998         do_dirty_record "> $f"
4999         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5000         do_dirty_record "echo blah > $f"
5001         [[ $before -eq $after ]] && error "write wasn't cached"
5002         do_dirty_record "sync"
5003         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5004         do_dirty_record "echo blah > $f"
5005         [[ $before -eq $after ]] && error "write wasn't cached"
5006         do_dirty_record "cancel_lru_locks osc"
5007         [[ $before -gt $after ]] ||
5008                 error "lock cancellation didn't lower dirty count"
5009         start_writeback
5010 }
5011 run_test 45 "osc io page accounting ============================"
5012
5013 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5014 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5015 # objects offset and an assert hit when an rpc was built with 1023's mapped
5016 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5017 test_46() {
5018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5019
5020         f="$DIR/f46"
5021         stop_writeback
5022         sync
5023         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5024         sync
5025         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5026         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5027         sync
5028         start_writeback
5029 }
5030 run_test 46 "dirtying a previously written page ================"
5031
5032 # test_47 is removed "Device nodes check" is moved to test_28
5033
5034 test_48a() { # bug 2399
5035         [ "$mds1_FSTYPE" = "zfs" ] &&
5036         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5037                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5038
5039         test_mkdir $DIR/$tdir
5040         cd $DIR/$tdir
5041         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5042         test_mkdir $DIR/$tdir
5043         touch foo || error "'touch foo' failed after recreating cwd"
5044         test_mkdir bar
5045         touch .foo || error "'touch .foo' failed after recreating cwd"
5046         test_mkdir .bar
5047         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5048         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5049         cd . || error "'cd .' failed after recreating cwd"
5050         mkdir . && error "'mkdir .' worked after recreating cwd"
5051         rmdir . && error "'rmdir .' worked after recreating cwd"
5052         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5053         cd .. || error "'cd ..' failed after recreating cwd"
5054 }
5055 run_test 48a "Access renamed working dir (should return errors)="
5056
5057 test_48b() { # bug 2399
5058         rm -rf $DIR/$tdir
5059         test_mkdir $DIR/$tdir
5060         cd $DIR/$tdir
5061         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5062         touch foo && error "'touch foo' worked after removing cwd"
5063         mkdir foo && error "'mkdir foo' worked after removing cwd"
5064         touch .foo && error "'touch .foo' worked after removing cwd"
5065         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5066         ls . > /dev/null && error "'ls .' worked after removing cwd"
5067         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5068         mkdir . && error "'mkdir .' worked after removing cwd"
5069         rmdir . && error "'rmdir .' worked after removing cwd"
5070         ln -s . foo && error "'ln -s .' worked after removing cwd"
5071         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5072 }
5073 run_test 48b "Access removed working dir (should return errors)="
5074
5075 test_48c() { # bug 2350
5076         #lctl set_param debug=-1
5077         #set -vx
5078         rm -rf $DIR/$tdir
5079         test_mkdir -p $DIR/$tdir/dir
5080         cd $DIR/$tdir/dir
5081         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5082         $TRACE touch foo && error "touch foo worked after removing cwd"
5083         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5084         touch .foo && error "touch .foo worked after removing cwd"
5085         mkdir .foo && error "mkdir .foo worked after removing cwd"
5086         $TRACE ls . && error "'ls .' worked after removing cwd"
5087         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5088         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5089         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5090         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5091         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5092 }
5093 run_test 48c "Access removed working subdir (should return errors)"
5094
5095 test_48d() { # bug 2350
5096         #lctl set_param debug=-1
5097         #set -vx
5098         rm -rf $DIR/$tdir
5099         test_mkdir -p $DIR/$tdir/dir
5100         cd $DIR/$tdir/dir
5101         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5102         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5103         $TRACE touch foo && error "'touch foo' worked after removing parent"
5104         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5105         touch .foo && error "'touch .foo' worked after removing parent"
5106         mkdir .foo && error "mkdir .foo worked after removing parent"
5107         $TRACE ls . && error "'ls .' worked after removing parent"
5108         $TRACE ls .. && error "'ls ..' worked after removing parent"
5109         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5110         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5111         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5112         true
5113 }
5114 run_test 48d "Access removed parent subdir (should return errors)"
5115
5116 test_48e() { # bug 4134
5117         #lctl set_param debug=-1
5118         #set -vx
5119         rm -rf $DIR/$tdir
5120         test_mkdir -p $DIR/$tdir/dir
5121         cd $DIR/$tdir/dir
5122         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5123         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5124         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5125         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5126         # On a buggy kernel addition of "touch foo" after cd .. will
5127         # produce kernel oops in lookup_hash_it
5128         touch ../foo && error "'cd ..' worked after recreate parent"
5129         cd $DIR
5130         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5131 }
5132 run_test 48e "Access to recreated parent subdir (should return errors)"
5133
5134 test_48f() {
5135         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5136                 skip "need MDS >= 2.13.55"
5137         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5138         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5139                 skip "needs different host for mdt1 mdt2"
5140         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5141
5142         $LFS mkdir -i0 $DIR/$tdir
5143         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5144
5145         for d in sub1 sub2 sub3; do
5146                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5147                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5148                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5149         done
5150
5151         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5152 }
5153 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5154
5155 test_49() { # LU-1030
5156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5157         remote_ost_nodsh && skip "remote OST with nodsh"
5158
5159         # get ost1 size - $FSNAME-OST0000
5160         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5161                 awk '{ print $4 }')
5162         # write 800M at maximum
5163         [[ $ost1_size -lt 2 ]] && ost1_size=2
5164         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5165
5166         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5167         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5168         local dd_pid=$!
5169
5170         # change max_pages_per_rpc while writing the file
5171         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5172         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5173         # loop until dd process exits
5174         while ps ax -opid | grep -wq $dd_pid; do
5175                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5176                 sleep $((RANDOM % 5 + 1))
5177         done
5178         # restore original max_pages_per_rpc
5179         $LCTL set_param $osc1_mppc=$orig_mppc
5180         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5181 }
5182 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5183
5184 test_50() {
5185         # bug 1485
5186         test_mkdir $DIR/$tdir
5187         cd $DIR/$tdir
5188         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5189 }
5190 run_test 50 "special situations: /proc symlinks  ==============="
5191
5192 test_51a() {    # was test_51
5193         # bug 1516 - create an empty entry right after ".." then split dir
5194         test_mkdir -c1 $DIR/$tdir
5195         touch $DIR/$tdir/foo
5196         $MCREATE $DIR/$tdir/bar
5197         rm $DIR/$tdir/foo
5198         createmany -m $DIR/$tdir/longfile 201
5199         FNUM=202
5200         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5201                 $MCREATE $DIR/$tdir/longfile$FNUM
5202                 FNUM=$(($FNUM + 1))
5203                 echo -n "+"
5204         done
5205         echo
5206         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5207 }
5208 run_test 51a "special situations: split htree with empty entry =="
5209
5210 cleanup_print_lfs_df () {
5211         trap 0
5212         $LFS df
5213         $LFS df -i
5214 }
5215
5216 test_51b() {
5217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5218
5219         local dir=$DIR/$tdir
5220         local nrdirs=$((65536 + 100))
5221
5222         # cleanup the directory
5223         rm -fr $dir
5224
5225         test_mkdir -c1 $dir
5226
5227         $LFS df
5228         $LFS df -i
5229         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5230         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5231         [[ $numfree -lt $nrdirs ]] &&
5232                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5233
5234         # need to check free space for the directories as well
5235         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5236         numfree=$(( blkfree / $(fs_inode_ksize) ))
5237         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5238
5239         trap cleanup_print_lfs_df EXIT
5240
5241         # create files
5242         createmany -d $dir/d $nrdirs || {
5243                 unlinkmany $dir/d $nrdirs
5244                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5245         }
5246
5247         # really created :
5248         nrdirs=$(ls -U $dir | wc -l)
5249
5250         # unlink all but 100 subdirectories, then check it still works
5251         local left=100
5252         local delete=$((nrdirs - left))
5253
5254         $LFS df
5255         $LFS df -i
5256
5257         # for ldiskfs the nlink count should be 1, but this is OSD specific
5258         # and so this is listed for informational purposes only
5259         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5260         unlinkmany -d $dir/d $delete ||
5261                 error "unlink of first $delete subdirs failed"
5262
5263         echo "nlink between: $(stat -c %h $dir)"
5264         local found=$(ls -U $dir | wc -l)
5265         [ $found -ne $left ] &&
5266                 error "can't find subdirs: found only $found, expected $left"
5267
5268         unlinkmany -d $dir/d $delete $left ||
5269                 error "unlink of second $left subdirs failed"
5270         # regardless of whether the backing filesystem tracks nlink accurately
5271         # or not, the nlink count shouldn't be more than "." and ".." here
5272         local after=$(stat -c %h $dir)
5273         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5274                 echo "nlink after: $after"
5275
5276         cleanup_print_lfs_df
5277 }
5278 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5279
5280 test_51d() {
5281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5282         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5283
5284         test_mkdir $DIR/$tdir
5285         createmany -o $DIR/$tdir/t- 1000
5286         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5287         for N in $(seq 0 $((OSTCOUNT - 1))); do
5288                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5289                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5290                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5291                         '($1 == '$N') { objs += 1 } \
5292                         END { printf("%0.0f", objs) }')
5293                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5294         done
5295         unlinkmany $DIR/$tdir/t- 1000
5296
5297         NLAST=0
5298         for N in $(seq 1 $((OSTCOUNT - 1))); do
5299                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5300                         error "OST $N has less objects vs OST $NLAST" \
5301                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5302                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5303                         error "OST $N has less objects vs OST $NLAST" \
5304                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5305
5306                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5307                         error "OST $N has less #0 objects vs OST $NLAST" \
5308                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5309                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5310                         error "OST $N has less #0 objects vs OST $NLAST" \
5311                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5312                 NLAST=$N
5313         done
5314         rm -f $TMP/$tfile
5315 }
5316 run_test 51d "check object distribution"
5317
5318 test_51e() {
5319         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5320                 skip_env "ldiskfs only test"
5321         fi
5322
5323         test_mkdir -c1 $DIR/$tdir
5324         test_mkdir -c1 $DIR/$tdir/d0
5325
5326         touch $DIR/$tdir/d0/foo
5327         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5328                 error "file exceed 65000 nlink limit!"
5329         unlinkmany $DIR/$tdir/d0/f- 65001
5330         return 0
5331 }
5332 run_test 51e "check file nlink limit"
5333
5334 test_51f() {
5335         test_mkdir $DIR/$tdir
5336
5337         local max=100000
5338         local ulimit_old=$(ulimit -n)
5339         local spare=20 # number of spare fd's for scripts/libraries, etc.
5340         local mdt=$($LFS getstripe -m $DIR/$tdir)
5341         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5342
5343         echo "MDT$mdt numfree=$numfree, max=$max"
5344         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5345         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5346                 while ! ulimit -n $((numfree + spare)); do
5347                         numfree=$((numfree * 3 / 4))
5348                 done
5349                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5350         else
5351                 echo "left ulimit at $ulimit_old"
5352         fi
5353
5354         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5355                 unlinkmany $DIR/$tdir/f $numfree
5356                 error "create+open $numfree files in $DIR/$tdir failed"
5357         }
5358         ulimit -n $ulimit_old
5359
5360         # if createmany exits at 120s there will be fewer than $numfree files
5361         unlinkmany $DIR/$tdir/f $numfree || true
5362 }
5363 run_test 51f "check many open files limit"
5364
5365 test_52a() {
5366         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5367         test_mkdir $DIR/$tdir
5368         touch $DIR/$tdir/foo
5369         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5370         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5371         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5372         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5373         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5374                                         error "link worked"
5375         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5376         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5377         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5378                                                      error "lsattr"
5379         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5380         cp -r $DIR/$tdir $TMP/
5381         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5382 }
5383 run_test 52a "append-only flag test (should return errors)"
5384
5385 test_52b() {
5386         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5387         test_mkdir $DIR/$tdir
5388         touch $DIR/$tdir/foo
5389         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5390         cat test > $DIR/$tdir/foo && error "cat test worked"
5391         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5392         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5393         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5394                                         error "link worked"
5395         echo foo >> $DIR/$tdir/foo && error "echo worked"
5396         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5397         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5398         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5399         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5400                                                         error "lsattr"
5401         chattr -i $DIR/$tdir/foo || error "chattr failed"
5402
5403         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5404 }
5405 run_test 52b "immutable flag test (should return errors) ======="
5406
5407 test_53() {
5408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5409         remote_mds_nodsh && skip "remote MDS with nodsh"
5410         remote_ost_nodsh && skip "remote OST with nodsh"
5411
5412         local param
5413         local param_seq
5414         local ostname
5415         local mds_last
5416         local mds_last_seq
5417         local ost_last
5418         local ost_last_seq
5419         local ost_last_id
5420         local ostnum
5421         local node
5422         local found=false
5423         local support_last_seq=true
5424
5425         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5426                 support_last_seq=false
5427
5428         # only test MDT0000
5429         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5430         local value
5431         for value in $(do_facet $SINGLEMDS \
5432                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5433                 param=$(echo ${value[0]} | cut -d "=" -f1)
5434                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5435
5436                 if $support_last_seq; then
5437                         param_seq=$(echo $param |
5438                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5439                         mds_last_seq=$(do_facet $SINGLEMDS \
5440                                        $LCTL get_param -n $param_seq)
5441                 fi
5442                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5443
5444                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5445                 node=$(facet_active_host ost$((ostnum+1)))
5446                 param="obdfilter.$ostname.last_id"
5447                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5448                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5449                         ost_last_id=$ost_last
5450
5451                         if $support_last_seq; then
5452                                 ost_last_id=$(echo $ost_last |
5453                                               awk -F':' '{print $2}' |
5454                                               sed -e "s/^0x//g")
5455                                 ost_last_seq=$(echo $ost_last |
5456                                                awk -F':' '{print $1}')
5457                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5458                         fi
5459
5460                         if [[ $ost_last_id != $mds_last ]]; then
5461                                 error "$ost_last_id != $mds_last"
5462                         else
5463                                 found=true
5464                                 break
5465                         fi
5466                 done
5467         done
5468         $found || error "can not match last_seq/last_id for $mdtosc"
5469         return 0
5470 }
5471 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5472
5473 test_54a() {
5474         perl -MSocket -e ';' || skip "no Socket perl module installed"
5475
5476         $SOCKETSERVER $DIR/socket ||
5477                 error "$SOCKETSERVER $DIR/socket failed: $?"
5478         $SOCKETCLIENT $DIR/socket ||
5479                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5480         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5481 }
5482 run_test 54a "unix domain socket test =========================="
5483
5484 test_54b() {
5485         f="$DIR/f54b"
5486         mknod $f c 1 3
5487         chmod 0666 $f
5488         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5489 }
5490 run_test 54b "char device works in lustre ======================"
5491
5492 find_loop_dev() {
5493         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5494         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5495         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5496
5497         for i in $(seq 3 7); do
5498                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5499                 LOOPDEV=$LOOPBASE$i
5500                 LOOPNUM=$i
5501                 break
5502         done
5503 }
5504
5505 cleanup_54c() {
5506         local rc=0
5507         loopdev="$DIR/loop54c"
5508
5509         trap 0
5510         $UMOUNT $DIR/$tdir || rc=$?
5511         losetup -d $loopdev || true
5512         losetup -d $LOOPDEV || true
5513         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5514         return $rc
5515 }
5516
5517 test_54c() {
5518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5519
5520         loopdev="$DIR/loop54c"
5521
5522         find_loop_dev
5523         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5524         trap cleanup_54c EXIT
5525         mknod $loopdev b 7 $LOOPNUM
5526         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5527         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5528         losetup $loopdev $DIR/$tfile ||
5529                 error "can't set up $loopdev for $DIR/$tfile"
5530         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5531         test_mkdir $DIR/$tdir
5532         mount -t ext2 $loopdev $DIR/$tdir ||
5533                 error "error mounting $loopdev on $DIR/$tdir"
5534         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5535                 error "dd write"
5536         df $DIR/$tdir
5537         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5538                 error "dd read"
5539         cleanup_54c
5540 }
5541 run_test 54c "block device works in lustre ====================="
5542
5543 test_54d() {
5544         f="$DIR/f54d"
5545         string="aaaaaa"
5546         mknod $f p
5547         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5548 }
5549 run_test 54d "fifo device works in lustre ======================"
5550
5551 test_54e() {
5552         f="$DIR/f54e"
5553         string="aaaaaa"
5554         cp -aL /dev/console $f
5555         echo $string > $f || error "echo $string to $f failed"
5556 }
5557 run_test 54e "console/tty device works in lustre ======================"
5558
5559 test_56a() {
5560         local numfiles=3
5561         local dir=$DIR/$tdir
5562
5563         rm -rf $dir
5564         test_mkdir -p $dir/dir
5565         for i in $(seq $numfiles); do
5566                 touch $dir/file$i
5567                 touch $dir/dir/file$i
5568         done
5569
5570         local numcomp=$($LFS getstripe --component-count $dir)
5571
5572         [[ $numcomp == 0 ]] && numcomp=1
5573
5574         # test lfs getstripe with --recursive
5575         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5576
5577         [[ $filenum -eq $((numfiles * 2)) ]] ||
5578                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5579         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5580         [[ $filenum -eq $numfiles ]] ||
5581                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5582         echo "$LFS getstripe showed obdidx or l_ost_idx"
5583
5584         # test lfs getstripe with file instead of dir
5585         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5586         [[ $filenum -eq 1 ]] ||
5587                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5588         echo "$LFS getstripe file1 passed"
5589
5590         #test lfs getstripe with --verbose
5591         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5592         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5593                 error "$LFS getstripe --verbose $dir: "\
5594                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5595         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5596                 error "$LFS getstripe $dir: showed lmm_magic"
5597
5598         #test lfs getstripe with -v prints lmm_fid
5599         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5600         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5601                 error "$LFS getstripe -v $dir: "\
5602                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5603         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5604                 error "$LFS getstripe $dir: showed lmm_fid by default"
5605         echo "$LFS getstripe --verbose passed"
5606
5607         #check for FID information
5608         local fid1=$($LFS getstripe --fid $dir/file1)
5609         local fid2=$($LFS getstripe --verbose $dir/file1 |
5610                      awk '/lmm_fid: / { print $2; exit; }')
5611         local fid3=$($LFS path2fid $dir/file1)
5612
5613         [ "$fid1" != "$fid2" ] &&
5614                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5615         [ "$fid1" != "$fid3" ] &&
5616                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5617         echo "$LFS getstripe --fid passed"
5618
5619         #test lfs getstripe with --obd
5620         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5621                 error "$LFS getstripe --obd wrong_uuid: should return error"
5622
5623         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5624
5625         local ostidx=1
5626         local obduuid=$(ostuuid_from_index $ostidx)
5627         local found=$($LFS getstripe -r --obd $obduuid $dir |
5628                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5629
5630         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5631         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5632                 ((filenum--))
5633         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5634                 ((filenum--))
5635
5636         [[ $found -eq $filenum ]] ||
5637                 error "$LFS getstripe --obd: found $found expect $filenum"
5638         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5639                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5640                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5641                 error "$LFS getstripe --obd: should not show file on other obd"
5642         echo "$LFS getstripe --obd passed"
5643 }
5644 run_test 56a "check $LFS getstripe"
5645
5646 test_56b() {
5647         local dir=$DIR/$tdir
5648         local numdirs=3
5649
5650         test_mkdir $dir
5651         for i in $(seq $numdirs); do
5652                 test_mkdir $dir/dir$i
5653         done
5654
5655         # test lfs getdirstripe default mode is non-recursion, which is
5656         # different from lfs getstripe
5657         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5658
5659         [[ $dircnt -eq 1 ]] ||
5660                 error "$LFS getdirstripe: found $dircnt, not 1"
5661         dircnt=$($LFS getdirstripe --recursive $dir |
5662                 grep -c lmv_stripe_count)
5663         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5664                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5665 }
5666 run_test 56b "check $LFS getdirstripe"
5667
5668 test_56c() {
5669         remote_ost_nodsh && skip "remote OST with nodsh"
5670
5671         local ost_idx=0
5672         local ost_name=$(ostname_from_index $ost_idx)
5673         local old_status=$(ost_dev_status $ost_idx)
5674         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5675
5676         [[ -z "$old_status" ]] ||
5677                 skip_env "OST $ost_name is in $old_status status"
5678
5679         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5680         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5681                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5682         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5683                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5684                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5685         fi
5686
5687         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5688                 error "$LFS df -v showing inactive devices"
5689         sleep_maxage
5690
5691         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5692
5693         [[ "$new_status" =~ "D" ]] ||
5694                 error "$ost_name status is '$new_status', missing 'D'"
5695         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5696                 [[ "$new_status" =~ "N" ]] ||
5697                         error "$ost_name status is '$new_status', missing 'N'"
5698         fi
5699         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5700                 [[ "$new_status" =~ "f" ]] ||
5701                         error "$ost_name status is '$new_status', missing 'f'"
5702         fi
5703
5704         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5705         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5706                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5707         [[ -z "$p" ]] && restore_lustre_params < $p || true
5708         sleep_maxage
5709
5710         new_status=$(ost_dev_status $ost_idx)
5711         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5712                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5713         # can't check 'f' as devices may actually be on flash
5714 }
5715 run_test 56c "check 'lfs df' showing device status"
5716
5717 test_56d() {
5718         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
5719         local osts=$($LFS df -v $MOUNT | grep -c OST)
5720
5721         $LFS df $MOUNT
5722
5723         (( mdts == MDSCOUNT )) ||
5724                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
5725         (( osts == OSTCOUNT )) ||
5726                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
5727 }
5728 run_test 56d "'lfs df -v' prints only configured devices"
5729
5730 NUMFILES=3
5731 NUMDIRS=3
5732 setup_56() {
5733         local local_tdir="$1"
5734         local local_numfiles="$2"
5735         local local_numdirs="$3"
5736         local dir_params="$4"
5737         local dir_stripe_params="$5"
5738
5739         if [ ! -d "$local_tdir" ] ; then
5740                 test_mkdir -p $dir_stripe_params $local_tdir
5741                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5742                 for i in $(seq $local_numfiles) ; do
5743                         touch $local_tdir/file$i
5744                 done
5745                 for i in $(seq $local_numdirs) ; do
5746                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5747                         for j in $(seq $local_numfiles) ; do
5748                                 touch $local_tdir/dir$i/file$j
5749                         done
5750                 done
5751         fi
5752 }
5753
5754 setup_56_special() {
5755         local local_tdir=$1
5756         local local_numfiles=$2
5757         local local_numdirs=$3
5758
5759         setup_56 $local_tdir $local_numfiles $local_numdirs
5760
5761         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5762                 for i in $(seq $local_numfiles) ; do
5763                         mknod $local_tdir/loop${i}b b 7 $i
5764                         mknod $local_tdir/null${i}c c 1 3
5765                         ln -s $local_tdir/file1 $local_tdir/link${i}
5766                 done
5767                 for i in $(seq $local_numdirs) ; do
5768                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5769                         mknod $local_tdir/dir$i/null${i}c c 1 3
5770                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5771                 done
5772         fi
5773 }
5774
5775 test_56g() {
5776         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5777         local expected=$(($NUMDIRS + 2))
5778
5779         setup_56 $dir $NUMFILES $NUMDIRS
5780
5781         # test lfs find with -name
5782         for i in $(seq $NUMFILES) ; do
5783                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5784
5785                 [ $nums -eq $expected ] ||
5786                         error "lfs find -name '*$i' $dir wrong: "\
5787                               "found $nums, expected $expected"
5788         done
5789 }
5790 run_test 56g "check lfs find -name"
5791
5792 test_56h() {
5793         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5794         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5795
5796         setup_56 $dir $NUMFILES $NUMDIRS
5797
5798         # test lfs find with ! -name
5799         for i in $(seq $NUMFILES) ; do
5800                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5801
5802                 [ $nums -eq $expected ] ||
5803                         error "lfs find ! -name '*$i' $dir wrong: "\
5804                               "found $nums, expected $expected"
5805         done
5806 }
5807 run_test 56h "check lfs find ! -name"
5808
5809 test_56i() {
5810         local dir=$DIR/$tdir
5811
5812         test_mkdir $dir
5813
5814         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5815         local out=$($cmd)
5816
5817         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5818 }
5819 run_test 56i "check 'lfs find -ost UUID' skips directories"
5820
5821 test_56j() {
5822         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5823
5824         setup_56_special $dir $NUMFILES $NUMDIRS
5825
5826         local expected=$((NUMDIRS + 1))
5827         local cmd="$LFS find -type d $dir"
5828         local nums=$($cmd | wc -l)
5829
5830         [ $nums -eq $expected ] ||
5831                 error "'$cmd' wrong: found $nums, expected $expected"
5832 }
5833 run_test 56j "check lfs find -type d"
5834
5835 test_56k() {
5836         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5837
5838         setup_56_special $dir $NUMFILES $NUMDIRS
5839
5840         local expected=$(((NUMDIRS + 1) * NUMFILES))
5841         local cmd="$LFS find -type f $dir"
5842         local nums=$($cmd | wc -l)
5843
5844         [ $nums -eq $expected ] ||
5845                 error "'$cmd' wrong: found $nums, expected $expected"
5846 }
5847 run_test 56k "check lfs find -type f"
5848
5849 test_56l() {
5850         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5851
5852         setup_56_special $dir $NUMFILES $NUMDIRS
5853
5854         local expected=$((NUMDIRS + NUMFILES))
5855         local cmd="$LFS find -type b $dir"
5856         local nums=$($cmd | wc -l)
5857
5858         [ $nums -eq $expected ] ||
5859                 error "'$cmd' wrong: found $nums, expected $expected"
5860 }
5861 run_test 56l "check lfs find -type b"
5862
5863 test_56m() {
5864         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5865
5866         setup_56_special $dir $NUMFILES $NUMDIRS
5867
5868         local expected=$((NUMDIRS + NUMFILES))
5869         local cmd="$LFS find -type c $dir"
5870         local nums=$($cmd | wc -l)
5871         [ $nums -eq $expected ] ||
5872                 error "'$cmd' wrong: found $nums, expected $expected"
5873 }
5874 run_test 56m "check lfs find -type c"
5875
5876 test_56n() {
5877         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5878         setup_56_special $dir $NUMFILES $NUMDIRS
5879
5880         local expected=$((NUMDIRS + NUMFILES))
5881         local cmd="$LFS find -type l $dir"
5882         local nums=$($cmd | wc -l)
5883
5884         [ $nums -eq $expected ] ||
5885                 error "'$cmd' wrong: found $nums, expected $expected"
5886 }
5887 run_test 56n "check lfs find -type l"
5888
5889 test_56o() {
5890         local dir=$DIR/$tdir
5891
5892         setup_56 $dir $NUMFILES $NUMDIRS
5893         utime $dir/file1 > /dev/null || error "utime (1)"
5894         utime $dir/file2 > /dev/null || error "utime (2)"
5895         utime $dir/dir1 > /dev/null || error "utime (3)"
5896         utime $dir/dir2 > /dev/null || error "utime (4)"
5897         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5898         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5899
5900         local expected=4
5901         local nums=$($LFS find -mtime +0 $dir | wc -l)
5902
5903         [ $nums -eq $expected ] ||
5904                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5905
5906         expected=12
5907         cmd="$LFS find -mtime 0 $dir"
5908         nums=$($cmd | wc -l)
5909         [ $nums -eq $expected ] ||
5910                 error "'$cmd' wrong: found $nums, expected $expected"
5911 }
5912 run_test 56o "check lfs find -mtime for old files"
5913
5914 test_56ob() {
5915         local dir=$DIR/$tdir
5916         local expected=1
5917         local count=0
5918
5919         # just to make sure there is something that won't be found
5920         test_mkdir $dir
5921         touch $dir/$tfile.now
5922
5923         for age in year week day hour min; do
5924                 count=$((count + 1))
5925
5926                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5927                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5928                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5929
5930                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5931                 local nums=$($cmd | wc -l)
5932                 [ $nums -eq $expected ] ||
5933                         error "'$cmd' wrong: found $nums, expected $expected"
5934
5935                 cmd="$LFS find $dir -atime $count${age:0:1}"
5936                 nums=$($cmd | wc -l)
5937                 [ $nums -eq $expected ] ||
5938                         error "'$cmd' wrong: found $nums, expected $expected"
5939         done
5940
5941         sleep 2
5942         cmd="$LFS find $dir -ctime +1s -type f"
5943         nums=$($cmd | wc -l)
5944         (( $nums == $count * 2 + 1)) ||
5945                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
5946 }
5947 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5948
5949 test_newerXY_base() {
5950         local x=$1
5951         local y=$2
5952         local dir=$DIR/$tdir
5953         local ref
5954         local negref
5955
5956         if [ $y == "t" ]; then
5957                 if [ $x == "b" ]; then
5958                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5959                 else
5960                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5961                 fi
5962         else
5963                 ref=$DIR/$tfile.newer.$x$y
5964                 touch $ref || error "touch $ref failed"
5965         fi
5966         sleep 2
5967         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
5968         sleep 2
5969         if [ $y == "t" ]; then
5970                 if [ $x == "b" ]; then
5971                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5972                 else
5973                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5974                 fi
5975         else
5976                 negref=$DIR/$tfile.negnewer.$x$y
5977                 touch $negref || error "touch $negref failed"
5978         fi
5979
5980         local cmd="$LFS find $dir -newer$x$y $ref"
5981         local nums=$(eval $cmd | wc -l)
5982         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
5983
5984         [ $nums -eq $expected ] ||
5985                 error "'$cmd' wrong: found $nums, expected $expected"
5986
5987         cmd="$LFS find $dir ! -newer$x$y $negref"
5988         nums=$(eval $cmd | wc -l)
5989         [ $nums -eq $expected ] ||
5990                 error "'$cmd' wrong: found $nums, expected $expected"
5991
5992         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
5993         nums=$(eval $cmd | wc -l)
5994         [ $nums -eq $expected ] ||
5995                 error "'$cmd' wrong: found $nums, expected $expected"
5996
5997         rm -rf $DIR/*
5998 }
5999
6000 test_56oc() {
6001         test_newerXY_base "b" "t"
6002         test_newerXY_base "a" "a"
6003         test_newerXY_base "a" "m"
6004         test_newerXY_base "a" "c"
6005         test_newerXY_base "m" "a"
6006         test_newerXY_base "m" "m"
6007         test_newerXY_base "m" "c"
6008         test_newerXY_base "c" "a"
6009         test_newerXY_base "c" "m"
6010         test_newerXY_base "c" "c"
6011         test_newerXY_base "b" "b"
6012         test_newerXY_base "a" "t"
6013         test_newerXY_base "m" "t"
6014         test_newerXY_base "c" "t"
6015         test_newerXY_base "b" "t"
6016 }
6017 run_test 56oc "check lfs find -newerXY work"
6018
6019 btime_supported() {
6020         local dir=$DIR/$tdir
6021         local rc
6022
6023         mkdir -p $dir
6024         touch $dir/$tfile
6025         $LFS find $dir -btime -1d -type f
6026         rc=$?
6027         rm -rf $dir
6028         return $rc
6029 }
6030
6031 test_56od() {
6032         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6033                 ! btime_supported && skip "btime unsupported on MDS"
6034
6035         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6036                 ! btime_supported && skip "btime unsupported on clients"
6037
6038         local dir=$DIR/$tdir
6039         local ref=$DIR/$tfile.ref
6040         local negref=$DIR/$tfile.negref
6041
6042         mkdir $dir || error "mkdir $dir failed"
6043         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6044         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6045         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6046         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6047         touch $ref || error "touch $ref failed"
6048         # sleep 3 seconds at least
6049         sleep 3
6050
6051         local before=$(do_facet mds1 date +%s)
6052         local skew=$(($(date +%s) - before + 1))
6053
6054         if (( skew < 0 && skew > -5 )); then
6055                 sleep $((0 - skew + 1))
6056                 skew=0
6057         fi
6058
6059         # Set the dir stripe params to limit files all on MDT0,
6060         # otherwise we need to calc the max clock skew between
6061         # the client and MDTs.
6062         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6063         sleep 2
6064         touch $negref || error "touch $negref failed"
6065
6066         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6067         local nums=$($cmd | wc -l)
6068         local expected=$(((NUMFILES + 1) * NUMDIRS))
6069
6070         [ $nums -eq $expected ] ||
6071                 error "'$cmd' wrong: found $nums, expected $expected"
6072
6073         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6074         nums=$($cmd | wc -l)
6075         expected=$((NUMFILES + 1))
6076         [ $nums -eq $expected ] ||
6077                 error "'$cmd' wrong: found $nums, expected $expected"
6078
6079         [ $skew -lt 0 ] && return
6080
6081         local after=$(do_facet mds1 date +%s)
6082         local age=$((after - before + 1 + skew))
6083
6084         cmd="$LFS find $dir -btime -${age}s -type f"
6085         nums=$($cmd | wc -l)
6086         expected=$(((NUMFILES + 1) * NUMDIRS))
6087
6088         echo "Clock skew between client and server: $skew, age:$age"
6089         [ $nums -eq $expected ] ||
6090                 error "'$cmd' wrong: found $nums, expected $expected"
6091
6092         expected=$(($NUMDIRS + 1))
6093         cmd="$LFS find $dir -btime -${age}s -type d"
6094         nums=$($cmd | wc -l)
6095         [ $nums -eq $expected ] ||
6096                 error "'$cmd' wrong: found $nums, expected $expected"
6097         rm -f $ref $negref || error "Failed to remove $ref $negref"
6098 }
6099 run_test 56od "check lfs find -btime with units"
6100
6101 test_56p() {
6102         [ $RUNAS_ID -eq $UID ] &&
6103                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6104
6105         local dir=$DIR/$tdir
6106
6107         setup_56 $dir $NUMFILES $NUMDIRS
6108         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6109
6110         local expected=$NUMFILES
6111         local cmd="$LFS find -uid $RUNAS_ID $dir"
6112         local nums=$($cmd | wc -l)
6113
6114         [ $nums -eq $expected ] ||
6115                 error "'$cmd' wrong: found $nums, expected $expected"
6116
6117         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6118         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6119         nums=$($cmd | wc -l)
6120         [ $nums -eq $expected ] ||
6121                 error "'$cmd' wrong: found $nums, expected $expected"
6122 }
6123 run_test 56p "check lfs find -uid and ! -uid"
6124
6125 test_56q() {
6126         [ $RUNAS_ID -eq $UID ] &&
6127                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6128
6129         local dir=$DIR/$tdir
6130
6131         setup_56 $dir $NUMFILES $NUMDIRS
6132         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6133
6134         local expected=$NUMFILES
6135         local cmd="$LFS find -gid $RUNAS_GID $dir"
6136         local nums=$($cmd | wc -l)
6137
6138         [ $nums -eq $expected ] ||
6139                 error "'$cmd' wrong: found $nums, expected $expected"
6140
6141         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6142         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6143         nums=$($cmd | wc -l)
6144         [ $nums -eq $expected ] ||
6145                 error "'$cmd' wrong: found $nums, expected $expected"
6146 }
6147 run_test 56q "check lfs find -gid and ! -gid"
6148
6149 test_56r() {
6150         local dir=$DIR/$tdir
6151
6152         setup_56 $dir $NUMFILES $NUMDIRS
6153
6154         local expected=12
6155         local cmd="$LFS find -size 0 -type f -lazy $dir"
6156         local nums=$($cmd | wc -l)
6157
6158         [ $nums -eq $expected ] ||
6159                 error "'$cmd' wrong: found $nums, expected $expected"
6160         cmd="$LFS find -size 0 -type f $dir"
6161         nums=$($cmd | wc -l)
6162         [ $nums -eq $expected ] ||
6163                 error "'$cmd' wrong: found $nums, expected $expected"
6164
6165         expected=0
6166         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6167         nums=$($cmd | wc -l)
6168         [ $nums -eq $expected ] ||
6169                 error "'$cmd' wrong: found $nums, expected $expected"
6170         cmd="$LFS find ! -size 0 -type f $dir"
6171         nums=$($cmd | wc -l)
6172         [ $nums -eq $expected ] ||
6173                 error "'$cmd' wrong: found $nums, expected $expected"
6174
6175         echo "test" > $dir/$tfile
6176         echo "test2" > $dir/$tfile.2 && sync
6177         expected=1
6178         cmd="$LFS find -size 5 -type f -lazy $dir"
6179         nums=$($cmd | wc -l)
6180         [ $nums -eq $expected ] ||
6181                 error "'$cmd' wrong: found $nums, expected $expected"
6182         cmd="$LFS find -size 5 -type f $dir"
6183         nums=$($cmd | wc -l)
6184         [ $nums -eq $expected ] ||
6185                 error "'$cmd' wrong: found $nums, expected $expected"
6186
6187         expected=1
6188         cmd="$LFS find -size +5 -type f -lazy $dir"
6189         nums=$($cmd | wc -l)
6190         [ $nums -eq $expected ] ||
6191                 error "'$cmd' wrong: found $nums, expected $expected"
6192         cmd="$LFS find -size +5 -type f $dir"
6193         nums=$($cmd | wc -l)
6194         [ $nums -eq $expected ] ||
6195                 error "'$cmd' wrong: found $nums, expected $expected"
6196
6197         expected=2
6198         cmd="$LFS find -size +0 -type f -lazy $dir"
6199         nums=$($cmd | wc -l)
6200         [ $nums -eq $expected ] ||
6201                 error "'$cmd' wrong: found $nums, expected $expected"
6202         cmd="$LFS find -size +0 -type f $dir"
6203         nums=$($cmd | wc -l)
6204         [ $nums -eq $expected ] ||
6205                 error "'$cmd' wrong: found $nums, expected $expected"
6206
6207         expected=2
6208         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6209         nums=$($cmd | wc -l)
6210         [ $nums -eq $expected ] ||
6211                 error "'$cmd' wrong: found $nums, expected $expected"
6212         cmd="$LFS find ! -size -5 -type f $dir"
6213         nums=$($cmd | wc -l)
6214         [ $nums -eq $expected ] ||
6215                 error "'$cmd' wrong: found $nums, expected $expected"
6216
6217         expected=12
6218         cmd="$LFS find -size -5 -type f -lazy $dir"
6219         nums=$($cmd | wc -l)
6220         [ $nums -eq $expected ] ||
6221                 error "'$cmd' wrong: found $nums, expected $expected"
6222         cmd="$LFS find -size -5 -type f $dir"
6223         nums=$($cmd | wc -l)
6224         [ $nums -eq $expected ] ||
6225                 error "'$cmd' wrong: found $nums, expected $expected"
6226 }
6227 run_test 56r "check lfs find -size works"
6228
6229 test_56ra_sub() {
6230         local expected=$1
6231         local glimpses=$2
6232         local cmd="$3"
6233
6234         cancel_lru_locks $OSC
6235
6236         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6237         local nums=$($cmd | wc -l)
6238
6239         [ $nums -eq $expected ] ||
6240                 error "'$cmd' wrong: found $nums, expected $expected"
6241
6242         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6243
6244         if (( rpcs_before + glimpses != rpcs_after )); then
6245                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6246                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6247
6248                 if [[ $glimpses == 0 ]]; then
6249                         error "'$cmd' should not send glimpse RPCs to OST"
6250                 else
6251                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6252                 fi
6253         fi
6254 }
6255
6256 test_56ra() {
6257         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6258                 skip "MDS < 2.12.58 doesn't return LSOM data"
6259         local dir=$DIR/$tdir
6260         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6261
6262         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6263
6264         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6265         $LCTL set_param -n llite.*.statahead_agl=0
6266         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6267
6268         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6269         # open and close all files to ensure LSOM is updated
6270         cancel_lru_locks $OSC
6271         find $dir -type f | xargs cat > /dev/null
6272
6273         #   expect_found  glimpse_rpcs  command_to_run
6274         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6275         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6276         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6277         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6278
6279         echo "test" > $dir/$tfile
6280         echo "test2" > $dir/$tfile.2 && sync
6281         cancel_lru_locks $OSC
6282         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6283
6284         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6285         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6286         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6287         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6288
6289         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6290         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6291         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6292         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6293         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6294         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6295 }
6296 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6297
6298 test_56rb() {
6299         local dir=$DIR/$tdir
6300         local tmp=$TMP/$tfile.log
6301         local mdt_idx;
6302
6303         test_mkdir -p $dir || error "failed to mkdir $dir"
6304         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6305                 error "failed to setstripe $dir/$tfile"
6306         mdt_idx=$($LFS getdirstripe -i $dir)
6307         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6308
6309         stack_trap "rm -f $tmp" EXIT
6310         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6311         ! grep -q obd_uuid $tmp ||
6312                 error "failed to find --size +100K --ost 0 $dir"
6313         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6314         ! grep -q obd_uuid $tmp ||
6315                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6316 }
6317 run_test 56rb "check lfs find --size --ost/--mdt works"
6318
6319 test_56s() { # LU-611 #LU-9369
6320         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6321
6322         local dir=$DIR/$tdir
6323         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6324
6325         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6326         for i in $(seq $NUMDIRS); do
6327                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6328         done
6329
6330         local expected=$NUMDIRS
6331         local cmd="$LFS find -c $OSTCOUNT $dir"
6332         local nums=$($cmd | wc -l)
6333
6334         [ $nums -eq $expected ] || {
6335                 $LFS getstripe -R $dir
6336                 error "'$cmd' wrong: found $nums, expected $expected"
6337         }
6338
6339         expected=$((NUMDIRS + onestripe))
6340         cmd="$LFS find -stripe-count +0 -type f $dir"
6341         nums=$($cmd | wc -l)
6342         [ $nums -eq $expected ] || {
6343                 $LFS getstripe -R $dir
6344                 error "'$cmd' wrong: found $nums, expected $expected"
6345         }
6346
6347         expected=$onestripe
6348         cmd="$LFS find -stripe-count 1 -type f $dir"
6349         nums=$($cmd | wc -l)
6350         [ $nums -eq $expected ] || {
6351                 $LFS getstripe -R $dir
6352                 error "'$cmd' wrong: found $nums, expected $expected"
6353         }
6354
6355         cmd="$LFS find -stripe-count -2 -type f $dir"
6356         nums=$($cmd | wc -l)
6357         [ $nums -eq $expected ] || {
6358                 $LFS getstripe -R $dir
6359                 error "'$cmd' wrong: found $nums, expected $expected"
6360         }
6361
6362         expected=0
6363         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6364         nums=$($cmd | wc -l)
6365         [ $nums -eq $expected ] || {
6366                 $LFS getstripe -R $dir
6367                 error "'$cmd' wrong: found $nums, expected $expected"
6368         }
6369 }
6370 run_test 56s "check lfs find -stripe-count works"
6371
6372 test_56t() { # LU-611 #LU-9369
6373         local dir=$DIR/$tdir
6374
6375         setup_56 $dir 0 $NUMDIRS
6376         for i in $(seq $NUMDIRS); do
6377                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6378         done
6379
6380         local expected=$NUMDIRS
6381         local cmd="$LFS find -S 8M $dir"
6382         local nums=$($cmd | wc -l)
6383
6384         [ $nums -eq $expected ] || {
6385                 $LFS getstripe -R $dir
6386                 error "'$cmd' wrong: found $nums, expected $expected"
6387         }
6388         rm -rf $dir
6389
6390         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6391
6392         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6393
6394         expected=$(((NUMDIRS + 1) * NUMFILES))
6395         cmd="$LFS find -stripe-size 512k -type f $dir"
6396         nums=$($cmd | wc -l)
6397         [ $nums -eq $expected ] ||
6398                 error "'$cmd' wrong: found $nums, expected $expected"
6399
6400         cmd="$LFS find -stripe-size +320k -type f $dir"
6401         nums=$($cmd | wc -l)
6402         [ $nums -eq $expected ] ||
6403                 error "'$cmd' wrong: found $nums, expected $expected"
6404
6405         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6406         cmd="$LFS find -stripe-size +200k -type f $dir"
6407         nums=$($cmd | wc -l)
6408         [ $nums -eq $expected ] ||
6409                 error "'$cmd' wrong: found $nums, expected $expected"
6410
6411         cmd="$LFS find -stripe-size -640k -type f $dir"
6412         nums=$($cmd | wc -l)
6413         [ $nums -eq $expected ] ||
6414                 error "'$cmd' wrong: found $nums, expected $expected"
6415
6416         expected=4
6417         cmd="$LFS find -stripe-size 256k -type f $dir"
6418         nums=$($cmd | wc -l)
6419         [ $nums -eq $expected ] ||
6420                 error "'$cmd' wrong: found $nums, expected $expected"
6421
6422         cmd="$LFS find -stripe-size -320k -type f $dir"
6423         nums=$($cmd | wc -l)
6424         [ $nums -eq $expected ] ||
6425                 error "'$cmd' wrong: found $nums, expected $expected"
6426
6427         expected=0
6428         cmd="$LFS find -stripe-size 1024k -type f $dir"
6429         nums=$($cmd | wc -l)
6430         [ $nums -eq $expected ] ||
6431                 error "'$cmd' wrong: found $nums, expected $expected"
6432 }
6433 run_test 56t "check lfs find -stripe-size works"
6434
6435 test_56u() { # LU-611
6436         local dir=$DIR/$tdir
6437
6438         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6439
6440         if [[ $OSTCOUNT -gt 1 ]]; then
6441                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6442                 onestripe=4
6443         else
6444                 onestripe=0
6445         fi
6446
6447         local expected=$(((NUMDIRS + 1) * NUMFILES))
6448         local cmd="$LFS find -stripe-index 0 -type f $dir"
6449         local nums=$($cmd | wc -l)
6450
6451         [ $nums -eq $expected ] ||
6452                 error "'$cmd' wrong: found $nums, expected $expected"
6453
6454         expected=$onestripe
6455         cmd="$LFS find -stripe-index 1 -type f $dir"
6456         nums=$($cmd | wc -l)
6457         [ $nums -eq $expected ] ||
6458                 error "'$cmd' wrong: found $nums, expected $expected"
6459
6460         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6461         nums=$($cmd | wc -l)
6462         [ $nums -eq $expected ] ||
6463                 error "'$cmd' wrong: found $nums, expected $expected"
6464
6465         expected=0
6466         # This should produce an error and not return any files
6467         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6468         nums=$($cmd 2>/dev/null | wc -l)
6469         [ $nums -eq $expected ] ||
6470                 error "'$cmd' wrong: found $nums, expected $expected"
6471
6472         if [[ $OSTCOUNT -gt 1 ]]; then
6473                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6474                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6475                 nums=$($cmd | wc -l)
6476                 [ $nums -eq $expected ] ||
6477                         error "'$cmd' wrong: found $nums, expected $expected"
6478         fi
6479 }
6480 run_test 56u "check lfs find -stripe-index works"
6481
6482 test_56v() {
6483         local mdt_idx=0
6484         local dir=$DIR/$tdir
6485
6486         setup_56 $dir $NUMFILES $NUMDIRS
6487
6488         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6489         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6490
6491         for file in $($LFS find -m $UUID $dir); do
6492                 file_midx=$($LFS getstripe -m $file)
6493                 [ $file_midx -eq $mdt_idx ] ||
6494                         error "lfs find -m $UUID != getstripe -m $file_midx"
6495         done
6496 }
6497 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6498
6499 test_56w() {
6500         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6502
6503         local dir=$DIR/$tdir
6504
6505         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6506
6507         local stripe_size=$($LFS getstripe -S -d $dir) ||
6508                 error "$LFS getstripe -S -d $dir failed"
6509         stripe_size=${stripe_size%% *}
6510
6511         local file_size=$((stripe_size * OSTCOUNT))
6512         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6513         local required_space=$((file_num * file_size))
6514         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6515                            head -n1)
6516         [[ $free_space -le $((required_space / 1024)) ]] &&
6517                 skip_env "need $required_space, have $free_space kbytes"
6518
6519         local dd_bs=65536
6520         local dd_count=$((file_size / dd_bs))
6521
6522         # write data into the files
6523         local i
6524         local j
6525         local file
6526
6527         for i in $(seq $NUMFILES); do
6528                 file=$dir/file$i
6529                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6530                         error "write data into $file failed"
6531         done
6532         for i in $(seq $NUMDIRS); do
6533                 for j in $(seq $NUMFILES); do
6534                         file=$dir/dir$i/file$j
6535                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6536                                 error "write data into $file failed"
6537                 done
6538         done
6539
6540         # $LFS_MIGRATE will fail if hard link migration is unsupported
6541         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6542                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6543                         error "creating links to $dir/dir1/file1 failed"
6544         fi
6545
6546         local expected=-1
6547
6548         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6549
6550         # lfs_migrate file
6551         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6552
6553         echo "$cmd"
6554         eval $cmd || error "$cmd failed"
6555
6556         check_stripe_count $dir/file1 $expected
6557
6558         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6559         then
6560                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6561                 # OST 1 if it is on OST 0. This file is small enough to
6562                 # be on only one stripe.
6563                 file=$dir/migr_1_ost
6564                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6565                         error "write data into $file failed"
6566                 local obdidx=$($LFS getstripe -i $file)
6567                 local oldmd5=$(md5sum $file)
6568                 local newobdidx=0
6569
6570                 [[ $obdidx -eq 0 ]] && newobdidx=1
6571                 cmd="$LFS migrate -i $newobdidx $file"
6572                 echo $cmd
6573                 eval $cmd || error "$cmd failed"
6574
6575                 local realobdix=$($LFS getstripe -i $file)
6576                 local newmd5=$(md5sum $file)
6577
6578                 [[ $newobdidx -ne $realobdix ]] &&
6579                         error "new OST is different (was=$obdidx, "\
6580                               "wanted=$newobdidx, got=$realobdix)"
6581                 [[ "$oldmd5" != "$newmd5" ]] &&
6582                         error "md5sum differ: $oldmd5, $newmd5"
6583         fi
6584
6585         # lfs_migrate dir
6586         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6587         echo "$cmd"
6588         eval $cmd || error "$cmd failed"
6589
6590         for j in $(seq $NUMFILES); do
6591                 check_stripe_count $dir/dir1/file$j $expected
6592         done
6593
6594         # lfs_migrate works with lfs find
6595         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6596              $LFS_MIGRATE -y -c $expected"
6597         echo "$cmd"
6598         eval $cmd || error "$cmd failed"
6599
6600         for i in $(seq 2 $NUMFILES); do
6601                 check_stripe_count $dir/file$i $expected
6602         done
6603         for i in $(seq 2 $NUMDIRS); do
6604                 for j in $(seq $NUMFILES); do
6605                 check_stripe_count $dir/dir$i/file$j $expected
6606                 done
6607         done
6608 }
6609 run_test 56w "check lfs_migrate -c stripe_count works"
6610
6611 test_56wb() {
6612         local file1=$DIR/$tdir/file1
6613         local create_pool=false
6614         local initial_pool=$($LFS getstripe -p $DIR)
6615         local pool_list=()
6616         local pool=""
6617
6618         echo -n "Creating test dir..."
6619         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6620         echo "done."
6621
6622         echo -n "Creating test file..."
6623         touch $file1 || error "cannot create file"
6624         echo "done."
6625
6626         echo -n "Detecting existing pools..."
6627         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6628
6629         if [ ${#pool_list[@]} -gt 0 ]; then
6630                 echo "${pool_list[@]}"
6631                 for thispool in "${pool_list[@]}"; do
6632                         if [[ -z "$initial_pool" ||
6633                               "$initial_pool" != "$thispool" ]]; then
6634                                 pool="$thispool"
6635                                 echo "Using existing pool '$pool'"
6636                                 break
6637                         fi
6638                 done
6639         else
6640                 echo "none detected."
6641         fi
6642         if [ -z "$pool" ]; then
6643                 pool=${POOL:-testpool}
6644                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6645                 echo -n "Creating pool '$pool'..."
6646                 create_pool=true
6647                 pool_add $pool &> /dev/null ||
6648                         error "pool_add failed"
6649                 echo "done."
6650
6651                 echo -n "Adding target to pool..."
6652                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6653                         error "pool_add_targets failed"
6654                 echo "done."
6655         fi
6656
6657         echo -n "Setting pool using -p option..."
6658         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6659                 error "migrate failed rc = $?"
6660         echo "done."
6661
6662         echo -n "Verifying test file is in pool after migrating..."
6663         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6664                 error "file was not migrated to pool $pool"
6665         echo "done."
6666
6667         echo -n "Removing test file from pool '$pool'..."
6668         # "lfs migrate $file" won't remove the file from the pool
6669         # until some striping information is changed.
6670         $LFS migrate -c 1 $file1 &> /dev/null ||
6671                 error "cannot remove from pool"
6672         [ "$($LFS getstripe -p $file1)" ] &&
6673                 error "pool still set"
6674         echo "done."
6675
6676         echo -n "Setting pool using --pool option..."
6677         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6678                 error "migrate failed rc = $?"
6679         echo "done."
6680
6681         # Clean up
6682         rm -f $file1
6683         if $create_pool; then
6684                 destroy_test_pools 2> /dev/null ||
6685                         error "destroy test pools failed"
6686         fi
6687 }
6688 run_test 56wb "check lfs_migrate pool support"
6689
6690 test_56wc() {
6691         local file1="$DIR/$tdir/file1"
6692         local parent_ssize
6693         local parent_scount
6694         local cur_ssize
6695         local cur_scount
6696         local orig_ssize
6697
6698         echo -n "Creating test dir..."
6699         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6700         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6701                 error "cannot set stripe by '-S 1M -c 1'"
6702         echo "done"
6703
6704         echo -n "Setting initial stripe for test file..."
6705         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6706                 error "cannot set stripe"
6707         cur_ssize=$($LFS getstripe -S "$file1")
6708         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6709         echo "done."
6710
6711         # File currently set to -S 512K -c 1
6712
6713         # Ensure -c and -S options are rejected when -R is set
6714         echo -n "Verifying incompatible options are detected..."
6715         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6716                 error "incompatible -c and -R options not detected"
6717         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6718                 error "incompatible -S and -R options not detected"
6719         echo "done."
6720
6721         # Ensure unrecognized options are passed through to 'lfs migrate'
6722         echo -n "Verifying -S option is passed through to lfs migrate..."
6723         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6724                 error "migration failed"
6725         cur_ssize=$($LFS getstripe -S "$file1")
6726         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6727         echo "done."
6728
6729         # File currently set to -S 1M -c 1
6730
6731         # Ensure long options are supported
6732         echo -n "Verifying long options supported..."
6733         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6734                 error "long option without argument not supported"
6735         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6736                 error "long option with argument not supported"
6737         cur_ssize=$($LFS getstripe -S "$file1")
6738         [ $cur_ssize -eq 524288 ] ||
6739                 error "migrate --stripe-size $cur_ssize != 524288"
6740         echo "done."
6741
6742         # File currently set to -S 512K -c 1
6743
6744         if [ "$OSTCOUNT" -gt 1 ]; then
6745                 echo -n "Verifying explicit stripe count can be set..."
6746                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6747                         error "migrate failed"
6748                 cur_scount=$($LFS getstripe -c "$file1")
6749                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
6750                 echo "done."
6751         fi
6752
6753         # File currently set to -S 512K -c 1 or -S 512K -c 2
6754
6755         # Ensure parent striping is used if -R is set, and no stripe
6756         # count or size is specified
6757         echo -n "Setting stripe for parent directory..."
6758         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6759                 error "cannot set stripe '-S 2M -c 1'"
6760         echo "done."
6761
6762         echo -n "Verifying restripe option uses parent stripe settings..."
6763         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6764         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
6765         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6766                 error "migrate failed"
6767         cur_ssize=$($LFS getstripe -S "$file1")
6768         [ $cur_ssize -eq $parent_ssize ] ||
6769                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
6770         cur_scount=$($LFS getstripe -c "$file1")
6771         [ $cur_scount -eq $parent_scount ] ||
6772                 error "migrate -R stripe_count $cur_scount != $parent_scount"
6773         echo "done."
6774
6775         # File currently set to -S 1M -c 1
6776
6777         # Ensure striping is preserved if -R is not set, and no stripe
6778         # count or size is specified
6779         echo -n "Verifying striping size preserved when not specified..."
6780         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
6781         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6782                 error "cannot set stripe on parent directory"
6783         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6784                 error "migrate failed"
6785         cur_ssize=$($LFS getstripe -S "$file1")
6786         [ $cur_ssize -eq $orig_ssize ] ||
6787                 error "migrate by default $cur_ssize != $orig_ssize"
6788         echo "done."
6789
6790         # Ensure file name properly detected when final option has no argument
6791         echo -n "Verifying file name properly detected..."
6792         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6793                 error "file name interpreted as option argument"
6794         echo "done."
6795
6796         # Clean up
6797         rm -f "$file1"
6798 }
6799 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6800
6801 test_56wd() {
6802         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6803
6804         local file1=$DIR/$tdir/file1
6805
6806         echo -n "Creating test dir..."
6807         test_mkdir $DIR/$tdir || error "cannot create dir"
6808         echo "done."
6809
6810         echo -n "Creating test file..."
6811         touch $file1
6812         echo "done."
6813
6814         # Ensure 'lfs migrate' will fail by using a non-existent option,
6815         # and make sure rsync is not called to recover
6816         echo -n "Make sure --no-rsync option works..."
6817         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6818                 grep -q 'refusing to fall back to rsync' ||
6819                 error "rsync was called with --no-rsync set"
6820         echo "done."
6821
6822         # Ensure rsync is called without trying 'lfs migrate' first
6823         echo -n "Make sure --rsync option works..."
6824         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6825                 grep -q 'falling back to rsync' &&
6826                 error "lfs migrate was called with --rsync set"
6827         echo "done."
6828
6829         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6830         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6831                 grep -q 'at the same time' ||
6832                 error "--rsync and --no-rsync accepted concurrently"
6833         echo "done."
6834
6835         # Clean up
6836         rm -f $file1
6837 }
6838 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6839
6840 test_56we() {
6841         local td=$DIR/$tdir
6842         local tf=$td/$tfile
6843
6844         test_mkdir $td || error "cannot create $td"
6845         touch $tf || error "cannot touch $tf"
6846
6847         echo -n "Make sure --non-direct|-D works..."
6848         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
6849                 grep -q "lfs migrate --non-direct" ||
6850                 error "--non-direct option cannot work correctly"
6851         $LFS_MIGRATE -y -D -v $tf 2>&1 |
6852                 grep -q "lfs migrate -D" ||
6853                 error "-D option cannot work correctly"
6854         echo "done."
6855 }
6856 run_test 56we "check lfs_migrate --non-direct|-D support"
6857
6858 test_56x() {
6859         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6860         check_swap_layouts_support
6861
6862         local dir=$DIR/$tdir
6863         local ref1=/etc/passwd
6864         local file1=$dir/file1
6865
6866         test_mkdir $dir || error "creating dir $dir"
6867         $LFS setstripe -c 2 $file1
6868         cp $ref1 $file1
6869         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6870         stripe=$($LFS getstripe -c $file1)
6871         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6872         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6873
6874         # clean up
6875         rm -f $file1
6876 }
6877 run_test 56x "lfs migration support"
6878
6879 test_56xa() {
6880         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6881         check_swap_layouts_support
6882
6883         local dir=$DIR/$tdir/$testnum
6884
6885         test_mkdir -p $dir
6886
6887         local ref1=/etc/passwd
6888         local file1=$dir/file1
6889
6890         $LFS setstripe -c 2 $file1
6891         cp $ref1 $file1
6892         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6893
6894         local stripe=$($LFS getstripe -c $file1)
6895
6896         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6897         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6898
6899         # clean up
6900         rm -f $file1
6901 }
6902 run_test 56xa "lfs migration --block support"
6903
6904 check_migrate_links() {
6905         local dir="$1"
6906         local file1="$dir/file1"
6907         local begin="$2"
6908         local count="$3"
6909         local runas="$4"
6910         local total_count=$(($begin + $count - 1))
6911         local symlink_count=10
6912         local uniq_count=10
6913
6914         if [ ! -f "$file1" ]; then
6915                 echo -n "creating initial file..."
6916                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6917                         error "cannot setstripe initial file"
6918                 echo "done"
6919
6920                 echo -n "creating symlinks..."
6921                 for s in $(seq 1 $symlink_count); do
6922                         ln -s "$file1" "$dir/slink$s" ||
6923                                 error "cannot create symlinks"
6924                 done
6925                 echo "done"
6926
6927                 echo -n "creating nonlinked files..."
6928                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6929                         error "cannot create nonlinked files"
6930                 echo "done"
6931         fi
6932
6933         # create hard links
6934         if [ ! -f "$dir/file$total_count" ]; then
6935                 echo -n "creating hard links $begin:$total_count..."
6936                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6937                         /dev/null || error "cannot create hard links"
6938                 echo "done"
6939         fi
6940
6941         echo -n "checking number of hard links listed in xattrs..."
6942         local fid=$($LFS getstripe -F "$file1")
6943         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6944
6945         echo "${#paths[*]}"
6946         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6947                         skip "hard link list has unexpected size, skipping test"
6948         fi
6949         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6950                         error "link names should exceed xattrs size"
6951         fi
6952
6953         echo -n "migrating files..."
6954         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
6955         local rc=$?
6956         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6957         echo "done"
6958
6959         # make sure all links have been properly migrated
6960         echo -n "verifying files..."
6961         fid=$($LFS getstripe -F "$file1") ||
6962                 error "cannot get fid for file $file1"
6963         for i in $(seq 2 $total_count); do
6964                 local fid2=$($LFS getstripe -F $dir/file$i)
6965
6966                 [ "$fid2" == "$fid" ] ||
6967                         error "migrated hard link has mismatched FID"
6968         done
6969
6970         # make sure hard links were properly detected, and migration was
6971         # performed only once for the entire link set; nonlinked files should
6972         # also be migrated
6973         local actual=$(grep -c 'done' <<< "$migrate_out")
6974         local expected=$(($uniq_count + 1))
6975
6976         [ "$actual" -eq  "$expected" ] ||
6977                 error "hard links individually migrated ($actual != $expected)"
6978
6979         # make sure the correct number of hard links are present
6980         local hardlinks=$(stat -c '%h' "$file1")
6981
6982         [ $hardlinks -eq $total_count ] ||
6983                 error "num hard links $hardlinks != $total_count"
6984         echo "done"
6985
6986         return 0
6987 }
6988
6989 test_56xb() {
6990         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6991                 skip "Need MDS version at least 2.10.55"
6992
6993         local dir="$DIR/$tdir"
6994
6995         test_mkdir "$dir" || error "cannot create dir $dir"
6996
6997         echo "testing lfs migrate mode when all links fit within xattrs"
6998         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6999
7000         echo "testing rsync mode when all links fit within xattrs"
7001         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7002
7003         echo "testing lfs migrate mode when all links do not fit within xattrs"
7004         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7005
7006         echo "testing rsync mode when all links do not fit within xattrs"
7007         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7008
7009         chown -R $RUNAS_ID $dir
7010         echo "testing non-root lfs migrate mode when not all links are in xattr"
7011         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7012
7013         # clean up
7014         rm -rf $dir
7015 }
7016 run_test 56xb "lfs migration hard link support"
7017
7018 test_56xc() {
7019         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7020
7021         local dir="$DIR/$tdir"
7022
7023         test_mkdir "$dir" || error "cannot create dir $dir"
7024
7025         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7026         echo -n "Setting initial stripe for 20MB test file..."
7027         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7028                 error "cannot setstripe 20MB file"
7029         echo "done"
7030         echo -n "Sizing 20MB test file..."
7031         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7032         echo "done"
7033         echo -n "Verifying small file autostripe count is 1..."
7034         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7035                 error "cannot migrate 20MB file"
7036         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7037                 error "cannot get stripe for $dir/20mb"
7038         [ $stripe_count -eq 1 ] ||
7039                 error "unexpected stripe count $stripe_count for 20MB file"
7040         rm -f "$dir/20mb"
7041         echo "done"
7042
7043         # Test 2: File is small enough to fit within the available space on
7044         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7045         # have at least an additional 1KB for each desired stripe for test 3
7046         echo -n "Setting stripe for 1GB test file..."
7047         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7048         echo "done"
7049         echo -n "Sizing 1GB test file..."
7050         # File size is 1GB + 3KB
7051         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7052         echo "done"
7053
7054         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7055         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7056         if (( avail > 524288 * OSTCOUNT )); then
7057                 echo -n "Migrating 1GB file..."
7058                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7059                         error "cannot migrate 1GB file"
7060                 echo "done"
7061                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7062                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7063                         error "cannot getstripe for 1GB file"
7064                 [ $stripe_count -eq 2 ] ||
7065                         error "unexpected stripe count $stripe_count != 2"
7066                 echo "done"
7067         fi
7068
7069         # Test 3: File is too large to fit within the available space on
7070         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7071         if [ $OSTCOUNT -ge 3 ]; then
7072                 # The required available space is calculated as
7073                 # file size (1GB + 3KB) / OST count (3).
7074                 local kb_per_ost=349526
7075
7076                 echo -n "Migrating 1GB file with limit..."
7077                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7078                         error "cannot migrate 1GB file with limit"
7079                 echo "done"
7080
7081                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7082                 echo -n "Verifying 1GB autostripe count with limited space..."
7083                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7084                         error "unexpected stripe count $stripe_count (min 3)"
7085                 echo "done"
7086         fi
7087
7088         # clean up
7089         rm -rf $dir
7090 }
7091 run_test 56xc "lfs migration autostripe"
7092
7093 test_56xd() {
7094         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7095
7096         local dir=$DIR/$tdir
7097         local f_mgrt=$dir/$tfile.mgrt
7098         local f_yaml=$dir/$tfile.yaml
7099         local f_copy=$dir/$tfile.copy
7100         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7101         local layout_copy="-c 2 -S 2M -i 1"
7102         local yamlfile=$dir/yamlfile
7103         local layout_before;
7104         local layout_after;
7105
7106         test_mkdir "$dir" || error "cannot create dir $dir"
7107         $LFS setstripe $layout_yaml $f_yaml ||
7108                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7109         $LFS getstripe --yaml $f_yaml > $yamlfile
7110         $LFS setstripe $layout_copy $f_copy ||
7111                 error "cannot setstripe $f_copy with layout $layout_copy"
7112         touch $f_mgrt
7113         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7114
7115         # 1. test option --yaml
7116         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7117                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7118         layout_before=$(get_layout_param $f_yaml)
7119         layout_after=$(get_layout_param $f_mgrt)
7120         [ "$layout_after" == "$layout_before" ] ||
7121                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7122
7123         # 2. test option --copy
7124         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7125                 error "cannot migrate $f_mgrt with --copy $f_copy"
7126         layout_before=$(get_layout_param $f_copy)
7127         layout_after=$(get_layout_param $f_mgrt)
7128         [ "$layout_after" == "$layout_before" ] ||
7129                 error "lfs_migrate --copy: $layout_after != $layout_before"
7130 }
7131 run_test 56xd "check lfs_migrate --yaml and --copy support"
7132
7133 test_56xe() {
7134         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7135
7136         local dir=$DIR/$tdir
7137         local f_comp=$dir/$tfile
7138         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7139         local layout_before=""
7140         local layout_after=""
7141
7142         test_mkdir "$dir" || error "cannot create dir $dir"
7143         $LFS setstripe $layout $f_comp ||
7144                 error "cannot setstripe $f_comp with layout $layout"
7145         layout_before=$(get_layout_param $f_comp)
7146         dd if=/dev/zero of=$f_comp bs=1M count=4
7147
7148         # 1. migrate a comp layout file by lfs_migrate
7149         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7150         layout_after=$(get_layout_param $f_comp)
7151         [ "$layout_before" == "$layout_after" ] ||
7152                 error "lfs_migrate: $layout_before != $layout_after"
7153
7154         # 2. migrate a comp layout file by lfs migrate
7155         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7156         layout_after=$(get_layout_param $f_comp)
7157         [ "$layout_before" == "$layout_after" ] ||
7158                 error "lfs migrate: $layout_before != $layout_after"
7159 }
7160 run_test 56xe "migrate a composite layout file"
7161
7162 test_56xf() {
7163         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7164
7165         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7166                 skip "Need server version at least 2.13.53"
7167
7168         local dir=$DIR/$tdir
7169         local f_comp=$dir/$tfile
7170         local layout="-E 1M -c1 -E -1 -c2"
7171         local fid_before=""
7172         local fid_after=""
7173
7174         test_mkdir "$dir" || error "cannot create dir $dir"
7175         $LFS setstripe $layout $f_comp ||
7176                 error "cannot setstripe $f_comp with layout $layout"
7177         fid_before=$($LFS getstripe --fid $f_comp)
7178         dd if=/dev/zero of=$f_comp bs=1M count=4
7179
7180         # 1. migrate a comp layout file to a comp layout
7181         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7182         fid_after=$($LFS getstripe --fid $f_comp)
7183         [ "$fid_before" == "$fid_after" ] ||
7184                 error "comp-to-comp migrate: $fid_before != $fid_after"
7185
7186         # 2. migrate a comp layout file to a plain layout
7187         $LFS migrate -c2 $f_comp ||
7188                 error "cannot migrate $f_comp by lfs migrate"
7189         fid_after=$($LFS getstripe --fid $f_comp)
7190         [ "$fid_before" == "$fid_after" ] ||
7191                 error "comp-to-plain migrate: $fid_before != $fid_after"
7192
7193         # 3. migrate a plain layout file to a comp layout
7194         $LFS migrate $layout $f_comp ||
7195                 error "cannot migrate $f_comp by lfs migrate"
7196         fid_after=$($LFS getstripe --fid $f_comp)
7197         [ "$fid_before" == "$fid_after" ] ||
7198                 error "plain-to-comp migrate: $fid_before != $fid_after"
7199 }
7200 run_test 56xf "FID is not lost during migration of a composite layout file"
7201
7202 test_56y() {
7203         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7204                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7205
7206         local res=""
7207         local dir=$DIR/$tdir
7208         local f1=$dir/file1
7209         local f2=$dir/file2
7210
7211         test_mkdir -p $dir || error "creating dir $dir"
7212         touch $f1 || error "creating std file $f1"
7213         $MULTIOP $f2 H2c || error "creating released file $f2"
7214
7215         # a directory can be raid0, so ask only for files
7216         res=$($LFS find $dir -L raid0 -type f | wc -l)
7217         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7218
7219         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7220         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7221
7222         # only files can be released, so no need to force file search
7223         res=$($LFS find $dir -L released)
7224         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7225
7226         res=$($LFS find $dir -type f \! -L released)
7227         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7228 }
7229 run_test 56y "lfs find -L raid0|released"
7230
7231 test_56z() { # LU-4824
7232         # This checks to make sure 'lfs find' continues after errors
7233         # There are two classes of errors that should be caught:
7234         # - If multiple paths are provided, all should be searched even if one
7235         #   errors out
7236         # - If errors are encountered during the search, it should not terminate
7237         #   early
7238         local dir=$DIR/$tdir
7239         local i
7240
7241         test_mkdir $dir
7242         for i in d{0..9}; do
7243                 test_mkdir $dir/$i
7244                 touch $dir/$i/$tfile
7245         done
7246         $LFS find $DIR/non_existent_dir $dir &&
7247                 error "$LFS find did not return an error"
7248         # Make a directory unsearchable. This should NOT be the last entry in
7249         # directory order.  Arbitrarily pick the 6th entry
7250         chmod 700 $($LFS find $dir -type d | sed '6!d')
7251
7252         $RUNAS $LFS find $DIR/non_existent $dir
7253         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7254
7255         # The user should be able to see 10 directories and 9 files
7256         (( count == 19 )) ||
7257                 error "$LFS find found $count != 19 entries after error"
7258 }
7259 run_test 56z "lfs find should continue after an error"
7260
7261 test_56aa() { # LU-5937
7262         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7263
7264         local dir=$DIR/$tdir
7265
7266         mkdir $dir
7267         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7268
7269         createmany -o $dir/striped_dir/${tfile}- 1024
7270         local dirs=$($LFS find --size +8k $dir/)
7271
7272         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7273 }
7274 run_test 56aa "lfs find --size under striped dir"
7275
7276 test_56ab() { # LU-10705
7277         test_mkdir $DIR/$tdir
7278         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7279         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7280         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7281         # Flush writes to ensure valid blocks.  Need to be more thorough for
7282         # ZFS, since blocks are not allocated/returned to client immediately.
7283         sync_all_data
7284         wait_zfs_commit ost1 2
7285         cancel_lru_locks osc
7286         ls -ls $DIR/$tdir
7287
7288         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7289
7290         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7291
7292         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7293         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7294
7295         rm -f $DIR/$tdir/$tfile.[123]
7296 }
7297 run_test 56ab "lfs find --blocks"
7298
7299 test_56ba() {
7300         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7301                 skip "Need MDS version at least 2.10.50"
7302
7303         # Create composite files with one component
7304         local dir=$DIR/$tdir
7305
7306         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7307         # Create composite files with three components
7308         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7309         # Create non-composite files
7310         createmany -o $dir/${tfile}- 10
7311
7312         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7313
7314         [[ $nfiles == 10 ]] ||
7315                 error "lfs find -E 1M found $nfiles != 10 files"
7316
7317         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7318         [[ $nfiles == 25 ]] ||
7319                 error "lfs find ! -E 1M found $nfiles != 25 files"
7320
7321         # All files have a component that starts at 0
7322         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7323         [[ $nfiles == 35 ]] ||
7324                 error "lfs find --component-start 0 - $nfiles != 35 files"
7325
7326         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7327         [[ $nfiles == 15 ]] ||
7328                 error "lfs find --component-start 2M - $nfiles != 15 files"
7329
7330         # All files created here have a componenet that does not starts at 2M
7331         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7332         [[ $nfiles == 35 ]] ||
7333                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7334
7335         # Find files with a specified number of components
7336         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7337         [[ $nfiles == 15 ]] ||
7338                 error "lfs find --component-count 3 - $nfiles != 15 files"
7339
7340         # Remember non-composite files have a component count of zero
7341         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7342         [[ $nfiles == 10 ]] ||
7343                 error "lfs find --component-count 0 - $nfiles != 10 files"
7344
7345         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7346         [[ $nfiles == 20 ]] ||
7347                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7348
7349         # All files have a flag called "init"
7350         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7351         [[ $nfiles == 35 ]] ||
7352                 error "lfs find --component-flags init - $nfiles != 35 files"
7353
7354         # Multi-component files will have a component not initialized
7355         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7356         [[ $nfiles == 15 ]] ||
7357                 error "lfs find !--component-flags init - $nfiles != 15 files"
7358
7359         rm -rf $dir
7360
7361 }
7362 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7363
7364 test_56ca() {
7365         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7366                 skip "Need MDS version at least 2.10.57"
7367
7368         local td=$DIR/$tdir
7369         local tf=$td/$tfile
7370         local dir
7371         local nfiles
7372         local cmd
7373         local i
7374         local j
7375
7376         # create mirrored directories and mirrored files
7377         mkdir $td || error "mkdir $td failed"
7378         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7379         createmany -o $tf- 10 || error "create $tf- failed"
7380
7381         for i in $(seq 2); do
7382                 dir=$td/dir$i
7383                 mkdir $dir || error "mkdir $dir failed"
7384                 $LFS mirror create -N$((3 + i)) $dir ||
7385                         error "create mirrored dir $dir failed"
7386                 createmany -o $dir/$tfile- 10 ||
7387                         error "create $dir/$tfile- failed"
7388         done
7389
7390         # change the states of some mirrored files
7391         echo foo > $tf-6
7392         for i in $(seq 2); do
7393                 dir=$td/dir$i
7394                 for j in $(seq 4 9); do
7395                         echo foo > $dir/$tfile-$j
7396                 done
7397         done
7398
7399         # find mirrored files with specific mirror count
7400         cmd="$LFS find --mirror-count 3 --type f $td"
7401         nfiles=$($cmd | wc -l)
7402         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7403
7404         cmd="$LFS find ! --mirror-count 3 --type f $td"
7405         nfiles=$($cmd | wc -l)
7406         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7407
7408         cmd="$LFS find --mirror-count +2 --type f $td"
7409         nfiles=$($cmd | wc -l)
7410         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7411
7412         cmd="$LFS find --mirror-count -6 --type f $td"
7413         nfiles=$($cmd | wc -l)
7414         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7415
7416         # find mirrored files with specific file state
7417         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7418         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7419
7420         cmd="$LFS find --mirror-state=ro --type f $td"
7421         nfiles=$($cmd | wc -l)
7422         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7423
7424         cmd="$LFS find ! --mirror-state=ro --type f $td"
7425         nfiles=$($cmd | wc -l)
7426         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7427
7428         cmd="$LFS find --mirror-state=wp --type f $td"
7429         nfiles=$($cmd | wc -l)
7430         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7431
7432         cmd="$LFS find ! --mirror-state=sp --type f $td"
7433         nfiles=$($cmd | wc -l)
7434         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7435 }
7436 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7437
7438 test_57a() {
7439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7440         # note test will not do anything if MDS is not local
7441         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7442                 skip_env "ldiskfs only test"
7443         fi
7444         remote_mds_nodsh && skip "remote MDS with nodsh"
7445
7446         local MNTDEV="osd*.*MDT*.mntdev"
7447         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7448         [ -z "$DEV" ] && error "can't access $MNTDEV"
7449         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7450                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7451                         error "can't access $DEV"
7452                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7453                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7454                 rm $TMP/t57a.dump
7455         done
7456 }
7457 run_test 57a "verify MDS filesystem created with large inodes =="
7458
7459 test_57b() {
7460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7461         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7462                 skip_env "ldiskfs only test"
7463         fi
7464         remote_mds_nodsh && skip "remote MDS with nodsh"
7465
7466         local dir=$DIR/$tdir
7467         local filecount=100
7468         local file1=$dir/f1
7469         local fileN=$dir/f$filecount
7470
7471         rm -rf $dir || error "removing $dir"
7472         test_mkdir -c1 $dir
7473         local mdtidx=$($LFS getstripe -m $dir)
7474         local mdtname=MDT$(printf %04x $mdtidx)
7475         local facet=mds$((mdtidx + 1))
7476
7477         echo "mcreating $filecount files"
7478         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7479
7480         # verify that files do not have EAs yet
7481         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7482                 error "$file1 has an EA"
7483         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7484                 error "$fileN has an EA"
7485
7486         sync
7487         sleep 1
7488         df $dir  #make sure we get new statfs data
7489         local mdsfree=$(do_facet $facet \
7490                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7491         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7492         local file
7493
7494         echo "opening files to create objects/EAs"
7495         for file in $(seq -f $dir/f%g 1 $filecount); do
7496                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7497                         error "opening $file"
7498         done
7499
7500         # verify that files have EAs now
7501         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7502         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7503
7504         sleep 1  #make sure we get new statfs data
7505         df $dir
7506         local mdsfree2=$(do_facet $facet \
7507                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7508         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7509
7510         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7511                 if [ "$mdsfree" != "$mdsfree2" ]; then
7512                         error "MDC before $mdcfree != after $mdcfree2"
7513                 else
7514                         echo "MDC before $mdcfree != after $mdcfree2"
7515                         echo "unable to confirm if MDS has large inodes"
7516                 fi
7517         fi
7518         rm -rf $dir
7519 }
7520 run_test 57b "default LOV EAs are stored inside large inodes ==="
7521
7522 test_58() {
7523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7524         [ -z "$(which wiretest 2>/dev/null)" ] &&
7525                         skip_env "could not find wiretest"
7526
7527         wiretest
7528 }
7529 run_test 58 "verify cross-platform wire constants =============="
7530
7531 test_59() {
7532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7533
7534         echo "touch 130 files"
7535         createmany -o $DIR/f59- 130
7536         echo "rm 130 files"
7537         unlinkmany $DIR/f59- 130
7538         sync
7539         # wait for commitment of removal
7540         wait_delete_completed
7541 }
7542 run_test 59 "verify cancellation of llog records async ========="
7543
7544 TEST60_HEAD="test_60 run $RANDOM"
7545 test_60a() {
7546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7547         remote_mgs_nodsh && skip "remote MGS with nodsh"
7548         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7549                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7550                         skip_env "missing subtest run-llog.sh"
7551
7552         log "$TEST60_HEAD - from kernel mode"
7553         do_facet mgs "$LCTL dk > /dev/null"
7554         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7555         do_facet mgs $LCTL dk > $TMP/$tfile
7556
7557         # LU-6388: test llog_reader
7558         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7559         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7560         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7561                         skip_env "missing llog_reader"
7562         local fstype=$(facet_fstype mgs)
7563         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7564                 skip_env "Only for ldiskfs or zfs type mgs"
7565
7566         local mntpt=$(facet_mntpt mgs)
7567         local mgsdev=$(mgsdevname 1)
7568         local fid_list
7569         local fid
7570         local rec_list
7571         local rec
7572         local rec_type
7573         local obj_file
7574         local path
7575         local seq
7576         local oid
7577         local pass=true
7578
7579         #get fid and record list
7580         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7581                 tail -n 4))
7582         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7583                 tail -n 4))
7584         #remount mgs as ldiskfs or zfs type
7585         stop mgs || error "stop mgs failed"
7586         mount_fstype mgs || error "remount mgs failed"
7587         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7588                 fid=${fid_list[i]}
7589                 rec=${rec_list[i]}
7590                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7591                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7592                 oid=$((16#$oid))
7593
7594                 case $fstype in
7595                         ldiskfs )
7596                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7597                         zfs )
7598                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7599                 esac
7600                 echo "obj_file is $obj_file"
7601                 do_facet mgs $llog_reader $obj_file
7602
7603                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7604                         awk '{ print $3 }' | sed -e "s/^type=//g")
7605                 if [ $rec_type != $rec ]; then
7606                         echo "FAILED test_60a wrong record type $rec_type," \
7607                               "should be $rec"
7608                         pass=false
7609                         break
7610                 fi
7611
7612                 #check obj path if record type is LLOG_LOGID_MAGIC
7613                 if [ "$rec" == "1064553b" ]; then
7614                         path=$(do_facet mgs $llog_reader $obj_file |
7615                                 grep "path=" | awk '{ print $NF }' |
7616                                 sed -e "s/^path=//g")
7617                         if [ $obj_file != $mntpt/$path ]; then
7618                                 echo "FAILED test_60a wrong obj path" \
7619                                       "$montpt/$path, should be $obj_file"
7620                                 pass=false
7621                                 break
7622                         fi
7623                 fi
7624         done
7625         rm -f $TMP/$tfile
7626         #restart mgs before "error", otherwise it will block the next test
7627         stop mgs || error "stop mgs failed"
7628         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7629         $pass || error "test failed, see FAILED test_60a messages for specifics"
7630 }
7631 run_test 60a "llog_test run from kernel module and test llog_reader"
7632
7633 test_60b() { # bug 6411
7634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7635
7636         dmesg > $DIR/$tfile
7637         LLOG_COUNT=$(do_facet mgs dmesg |
7638                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7639                           /llog_[a-z]*.c:[0-9]/ {
7640                                 if (marker)
7641                                         from_marker++
7642                                 from_begin++
7643                           }
7644                           END {
7645                                 if (marker)
7646                                         print from_marker
7647                                 else
7648                                         print from_begin
7649                           }")
7650
7651         [[ $LLOG_COUNT -gt 120 ]] &&
7652                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7653 }
7654 run_test 60b "limit repeated messages from CERROR/CWARN"
7655
7656 test_60c() {
7657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7658
7659         echo "create 5000 files"
7660         createmany -o $DIR/f60c- 5000
7661 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7662         lctl set_param fail_loc=0x80000137
7663         unlinkmany $DIR/f60c- 5000
7664         lctl set_param fail_loc=0
7665 }
7666 run_test 60c "unlink file when mds full"
7667
7668 test_60d() {
7669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7670
7671         SAVEPRINTK=$(lctl get_param -n printk)
7672         # verify "lctl mark" is even working"
7673         MESSAGE="test message ID $RANDOM $$"
7674         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7675         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7676
7677         lctl set_param printk=0 || error "set lnet.printk failed"
7678         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7679         MESSAGE="new test message ID $RANDOM $$"
7680         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7681         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7682         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7683
7684         lctl set_param -n printk="$SAVEPRINTK"
7685 }
7686 run_test 60d "test printk console message masking"
7687
7688 test_60e() {
7689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7690         remote_mds_nodsh && skip "remote MDS with nodsh"
7691
7692         touch $DIR/$tfile
7693 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7694         do_facet mds1 lctl set_param fail_loc=0x15b
7695         rm $DIR/$tfile
7696 }
7697 run_test 60e "no space while new llog is being created"
7698
7699 test_60g() {
7700         local pid
7701         local i
7702
7703         test_mkdir -c $MDSCOUNT $DIR/$tdir
7704
7705         (
7706                 local index=0
7707                 while true; do
7708                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7709                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7710                                 2>/dev/null
7711                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7712                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7713                         index=$((index + 1))
7714                 done
7715         ) &
7716
7717         pid=$!
7718
7719         for i in {0..100}; do
7720                 # define OBD_FAIL_OSD_TXN_START    0x19a
7721                 local index=$((i % MDSCOUNT + 1))
7722
7723                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7724                         > /dev/null
7725                 sleep 0.01
7726         done
7727
7728         kill -9 $pid
7729
7730         for i in $(seq $MDSCOUNT); do
7731                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7732         done
7733
7734         mkdir $DIR/$tdir/new || error "mkdir failed"
7735         rmdir $DIR/$tdir/new || error "rmdir failed"
7736
7737         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7738                 -t namespace
7739         for i in $(seq $MDSCOUNT); do
7740                 wait_update_facet mds$i "$LCTL get_param -n \
7741                         mdd.$(facet_svc mds$i).lfsck_namespace |
7742                         awk '/^status/ { print \\\$2 }'" "completed"
7743         done
7744
7745         ls -R $DIR/$tdir || error "ls failed"
7746         rm -rf $DIR/$tdir || error "rmdir failed"
7747 }
7748 run_test 60g "transaction abort won't cause MDT hung"
7749
7750 test_60h() {
7751         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7752                 skip "Need MDS version at least 2.12.52"
7753         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7754
7755         local f
7756
7757         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7758         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7759         for fail_loc in 0x80000188 0x80000189; do
7760                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7761                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7762                         error "mkdir $dir-$fail_loc failed"
7763                 for i in {0..10}; do
7764                         # create may fail on missing stripe
7765                         echo $i > $DIR/$tdir-$fail_loc/$i
7766                 done
7767                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7768                         error "getdirstripe $tdir-$fail_loc failed"
7769                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7770                         error "migrate $tdir-$fail_loc failed"
7771                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7772                         error "getdirstripe $tdir-$fail_loc failed"
7773                 pushd $DIR/$tdir-$fail_loc
7774                 for f in *; do
7775                         echo $f | cmp $f - || error "$f data mismatch"
7776                 done
7777                 popd
7778                 rm -rf $DIR/$tdir-$fail_loc
7779         done
7780 }
7781 run_test 60h "striped directory with missing stripes can be accessed"
7782
7783 test_61a() {
7784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7785
7786         f="$DIR/f61"
7787         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7788         cancel_lru_locks osc
7789         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7790         sync
7791 }
7792 run_test 61a "mmap() writes don't make sync hang ================"
7793
7794 test_61b() {
7795         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7796 }
7797 run_test 61b "mmap() of unstriped file is successful"
7798
7799 # bug 2330 - insufficient obd_match error checking causes LBUG
7800 test_62() {
7801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7802
7803         f="$DIR/f62"
7804         echo foo > $f
7805         cancel_lru_locks osc
7806         lctl set_param fail_loc=0x405
7807         cat $f && error "cat succeeded, expect -EIO"
7808         lctl set_param fail_loc=0
7809 }
7810 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7811 # match every page all of the time.
7812 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7813
7814 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7815 # Though this test is irrelevant anymore, it helped to reveal some
7816 # other grant bugs (LU-4482), let's keep it.
7817 test_63a() {   # was test_63
7818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7819
7820         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7821
7822         for i in `seq 10` ; do
7823                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7824                 sleep 5
7825                 kill $!
7826                 sleep 1
7827         done
7828
7829         rm -f $DIR/f63 || true
7830 }
7831 run_test 63a "Verify oig_wait interruption does not crash ======="
7832
7833 # bug 2248 - async write errors didn't return to application on sync
7834 # bug 3677 - async write errors left page locked
7835 test_63b() {
7836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7837
7838         debugsave
7839         lctl set_param debug=-1
7840
7841         # ensure we have a grant to do async writes
7842         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7843         rm $DIR/$tfile
7844
7845         sync    # sync lest earlier test intercept the fail_loc
7846
7847         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7848         lctl set_param fail_loc=0x80000406
7849         $MULTIOP $DIR/$tfile Owy && \
7850                 error "sync didn't return ENOMEM"
7851         sync; sleep 2; sync     # do a real sync this time to flush page
7852         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7853                 error "locked page left in cache after async error" || true
7854         debugrestore
7855 }
7856 run_test 63b "async write errors should be returned to fsync ==="
7857
7858 test_64a () {
7859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7860
7861         lfs df $DIR
7862         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
7863 }
7864 run_test 64a "verify filter grant calculations (in kernel) ====="
7865
7866 test_64b () {
7867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7868
7869         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7870 }
7871 run_test 64b "check out-of-space detection on client"
7872
7873 test_64c() {
7874         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7875 }
7876 run_test 64c "verify grant shrink"
7877
7878 import_param() {
7879         local tgt=$1
7880         local param=$2
7881
7882         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
7883 }
7884
7885 # this does exactly what osc_request.c:osc_announce_cached() does in
7886 # order to calculate max amount of grants to ask from server
7887 want_grant() {
7888         local tgt=$1
7889
7890         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
7891         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
7892
7893         ((rpc_in_flight++));
7894         nrpages=$((nrpages * rpc_in_flight))
7895
7896         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
7897
7898         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7899
7900         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7901         local undirty=$((nrpages * PAGE_SIZE))
7902
7903         local max_extent_pages
7904         max_extent_pages=$(import_param $tgt grant_max_extent_size)
7905         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7906         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7907         local grant_extent_tax
7908         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7909
7910         undirty=$((undirty + nrextents * grant_extent_tax))
7911
7912         echo $undirty
7913 }
7914
7915 # this is size of unit for grant allocation. It should be equal to
7916 # what tgt_grant.c:tgt_grant_chunk() calculates
7917 grant_chunk() {
7918         local tgt=$1
7919         local max_brw_size
7920         local grant_extent_tax
7921
7922         max_brw_size=$(import_param $tgt max_brw_size)
7923
7924         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7925
7926         echo $(((max_brw_size + grant_extent_tax) * 2))
7927 }
7928
7929 test_64d() {
7930         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
7931                 skip "OST < 2.10.55 doesn't limit grants enough"
7932
7933         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
7934
7935         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
7936                 skip "no grant_param connect flag"
7937
7938         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
7939
7940         $LCTL set_param -n -n debug="$OLDDEBUG" || true
7941         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
7942
7943
7944         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7945         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
7946
7947         $LFS setstripe $DIR/$tfile -i 0 -c 1
7948         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
7949         ddpid=$!
7950
7951         while kill -0 $ddpid; do
7952                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7953
7954                 if [[ $cur_grant -gt $max_cur_granted ]]; then
7955                         kill $ddpid
7956                         error "cur_grant $cur_grant > $max_cur_granted"
7957                 fi
7958
7959                 sleep 1
7960         done
7961 }
7962 run_test 64d "check grant limit exceed"
7963
7964 check_grants() {
7965         local tgt=$1
7966         local expected=$2
7967         local msg=$3
7968         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7969
7970         ((cur_grants == expected)) ||
7971                 error "$msg: grants mismatch: $cur_grants, expected $expected"
7972 }
7973
7974 round_up_p2() {
7975         echo $((($1 + $2 - 1) & ~($2 - 1)))
7976 }
7977
7978 test_64e() {
7979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7980         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
7981                 skip "Need OSS version at least 2.11.56"
7982
7983         # Remount client to reset grant
7984         remount_client $MOUNT || error "failed to remount client"
7985         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
7986
7987         local init_grants=$(import_param $osc_tgt initial_grant)
7988
7989         check_grants $osc_tgt $init_grants "init grants"
7990
7991         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
7992         local max_brw_size=$(import_param $osc_tgt max_brw_size)
7993         local gbs=$(import_param $osc_tgt grant_block_size)
7994
7995         # write random number of bytes from max_brw_size / 4 to max_brw_size
7996         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
7997         # align for direct io
7998         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
7999         # round to grant consumption unit
8000         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8001
8002         local grants=$((wb_round_up + extent_tax))
8003
8004         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8005
8006         # define OBD_FAIL_TGT_NO_GRANT 0x725
8007         # make the server not grant more back
8008         do_facet ost1 $LCTL set_param fail_loc=0x725
8009         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8010
8011         do_facet ost1 $LCTL set_param fail_loc=0
8012
8013         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8014
8015         rm -f $DIR/$tfile || error "rm failed"
8016
8017         # Remount client to reset grant
8018         remount_client $MOUNT || error "failed to remount client"
8019         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8020
8021         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8022
8023         # define OBD_FAIL_TGT_NO_GRANT 0x725
8024         # make the server not grant more back
8025         do_facet ost1 $LCTL set_param fail_loc=0x725
8026         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8027         do_facet ost1 $LCTL set_param fail_loc=0
8028
8029         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8030 }
8031 run_test 64e "check grant consumption (no grant allocation)"
8032
8033 test_64f() {
8034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8035
8036         # Remount client to reset grant
8037         remount_client $MOUNT || error "failed to remount client"
8038         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8039
8040         local init_grants=$(import_param $osc_tgt initial_grant)
8041         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8042         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8043         local gbs=$(import_param $osc_tgt grant_block_size)
8044         local chunk=$(grant_chunk $osc_tgt)
8045
8046         # write random number of bytes from max_brw_size / 4 to max_brw_size
8047         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8048         # align for direct io
8049         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8050         # round to grant consumption unit
8051         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8052
8053         local grants=$((wb_round_up + extent_tax))
8054
8055         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8056         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8057                 error "error writing to $DIR/$tfile"
8058
8059         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8060                 "direct io with grant allocation"
8061
8062         rm -f $DIR/$tfile || error "rm failed"
8063
8064         # Remount client to reset grant
8065         remount_client $MOUNT || error "failed to remount client"
8066         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8067
8068         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8069
8070         local cmd="oO_WRONLY:w${write_bytes}_yc"
8071
8072         $MULTIOP $DIR/$tfile $cmd &
8073         MULTIPID=$!
8074         sleep 1
8075
8076         check_grants $osc_tgt $((init_grants - grants)) \
8077                 "buffered io, not write rpc"
8078
8079         kill -USR1 $MULTIPID
8080         wait
8081
8082         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8083                 "buffered io, one RPC"
8084 }
8085 run_test 64f "check grant consumption (with grant allocation)"
8086
8087 # bug 1414 - set/get directories' stripe info
8088 test_65a() {
8089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8090
8091         test_mkdir $DIR/$tdir
8092         touch $DIR/$tdir/f1
8093         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8094 }
8095 run_test 65a "directory with no stripe info"
8096
8097 test_65b() {
8098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8099
8100         test_mkdir $DIR/$tdir
8101         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8102
8103         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8104                                                 error "setstripe"
8105         touch $DIR/$tdir/f2
8106         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8107 }
8108 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8109
8110 test_65c() {
8111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8112         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8113
8114         test_mkdir $DIR/$tdir
8115         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8116
8117         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8118                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8119         touch $DIR/$tdir/f3
8120         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8121 }
8122 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8123
8124 test_65d() {
8125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8126
8127         test_mkdir $DIR/$tdir
8128         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8129         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8130
8131         if [[ $STRIPECOUNT -le 0 ]]; then
8132                 sc=1
8133         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8134                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8135                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8136         else
8137                 sc=$(($STRIPECOUNT - 1))
8138         fi
8139         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8140         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8141         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8142                 error "lverify failed"
8143 }
8144 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8145
8146 test_65e() {
8147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8148
8149         test_mkdir $DIR/$tdir
8150
8151         $LFS setstripe $DIR/$tdir || error "setstripe"
8152         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8153                                         error "no stripe info failed"
8154         touch $DIR/$tdir/f6
8155         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8156 }
8157 run_test 65e "directory setstripe defaults"
8158
8159 test_65f() {
8160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8161
8162         test_mkdir $DIR/${tdir}f
8163         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8164                 error "setstripe succeeded" || true
8165 }
8166 run_test 65f "dir setstripe permission (should return error) ==="
8167
8168 test_65g() {
8169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8170
8171         test_mkdir $DIR/$tdir
8172         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8173
8174         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8175                 error "setstripe -S failed"
8176         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8177         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8178                 error "delete default stripe failed"
8179 }
8180 run_test 65g "directory setstripe -d"
8181
8182 test_65h() {
8183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8184
8185         test_mkdir $DIR/$tdir
8186         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8187
8188         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8189                 error "setstripe -S failed"
8190         test_mkdir $DIR/$tdir/dd1
8191         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8192                 error "stripe info inherit failed"
8193 }
8194 run_test 65h "directory stripe info inherit ===================="
8195
8196 test_65i() {
8197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8198
8199         save_layout_restore_at_exit $MOUNT
8200
8201         # bug6367: set non-default striping on root directory
8202         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8203
8204         # bug12836: getstripe on -1 default directory striping
8205         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8206
8207         # bug12836: getstripe -v on -1 default directory striping
8208         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8209
8210         # bug12836: new find on -1 default directory striping
8211         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8212 }
8213 run_test 65i "various tests to set root directory striping"
8214
8215 test_65j() { # bug6367
8216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8217
8218         sync; sleep 1
8219
8220         # if we aren't already remounting for each test, do so for this test
8221         if [ "$I_MOUNTED" = "yes" ]; then
8222                 cleanup || error "failed to unmount"
8223                 setup
8224         fi
8225
8226         save_layout_restore_at_exit $MOUNT
8227
8228         $LFS setstripe -d $MOUNT || error "setstripe failed"
8229 }
8230 run_test 65j "set default striping on root directory (bug 6367)="
8231
8232 cleanup_65k() {
8233         rm -rf $DIR/$tdir
8234         wait_delete_completed
8235         do_facet $SINGLEMDS "lctl set_param -n \
8236                 osp.$ost*MDT0000.max_create_count=$max_count"
8237         do_facet $SINGLEMDS "lctl set_param -n \
8238                 osp.$ost*MDT0000.create_count=$count"
8239         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8240         echo $INACTIVE_OSC "is Activate"
8241
8242         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8243 }
8244
8245 test_65k() { # bug11679
8246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8247         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8248         remote_mds_nodsh && skip "remote MDS with nodsh"
8249
8250         local disable_precreate=true
8251         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8252                 disable_precreate=false
8253
8254         echo "Check OST status: "
8255         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8256                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8257
8258         for OSC in $MDS_OSCS; do
8259                 echo $OSC "is active"
8260                 do_facet $SINGLEMDS lctl --device %$OSC activate
8261         done
8262
8263         for INACTIVE_OSC in $MDS_OSCS; do
8264                 local ost=$(osc_to_ost $INACTIVE_OSC)
8265                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8266                                lov.*md*.target_obd |
8267                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8268
8269                 mkdir -p $DIR/$tdir
8270                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8271                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8272
8273                 echo "Deactivate: " $INACTIVE_OSC
8274                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8275
8276                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8277                               osp.$ost*MDT0000.create_count")
8278                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8279                                   osp.$ost*MDT0000.max_create_count")
8280                 $disable_precreate &&
8281                         do_facet $SINGLEMDS "lctl set_param -n \
8282                                 osp.$ost*MDT0000.max_create_count=0"
8283
8284                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8285                         [ -f $DIR/$tdir/$idx ] && continue
8286                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8287                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8288                                 { cleanup_65k;
8289                                   error "setstripe $idx should succeed"; }
8290                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8291                 done
8292                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8293                 rmdir $DIR/$tdir
8294
8295                 do_facet $SINGLEMDS "lctl set_param -n \
8296                         osp.$ost*MDT0000.max_create_count=$max_count"
8297                 do_facet $SINGLEMDS "lctl set_param -n \
8298                         osp.$ost*MDT0000.create_count=$count"
8299                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8300                 echo $INACTIVE_OSC "is Activate"
8301
8302                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8303         done
8304 }
8305 run_test 65k "validate manual striping works properly with deactivated OSCs"
8306
8307 test_65l() { # bug 12836
8308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8309
8310         test_mkdir -p $DIR/$tdir/test_dir
8311         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8312         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8313 }
8314 run_test 65l "lfs find on -1 stripe dir ========================"
8315
8316 test_65m() {
8317         local layout=$(save_layout $MOUNT)
8318         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8319                 restore_layout $MOUNT $layout
8320                 error "setstripe should fail by non-root users"
8321         }
8322         true
8323 }
8324 run_test 65m "normal user can't set filesystem default stripe"
8325
8326 test_65n() {
8327         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8328         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8329                 skip "Need MDS version at least 2.12.50"
8330         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8331
8332         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8333         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8334         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8335
8336         local root_layout=$(save_layout $MOUNT)
8337         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8338
8339         # new subdirectory under root directory should not inherit
8340         # the default layout from root
8341         local dir1=$MOUNT/$tdir-1
8342         mkdir $dir1 || error "mkdir $dir1 failed"
8343         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8344                 error "$dir1 shouldn't have LOV EA"
8345
8346         # delete the default layout on root directory
8347         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8348
8349         local dir2=$MOUNT/$tdir-2
8350         mkdir $dir2 || error "mkdir $dir2 failed"
8351         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8352                 error "$dir2 shouldn't have LOV EA"
8353
8354         # set a new striping pattern on root directory
8355         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8356         local new_def_stripe_size=$((def_stripe_size * 2))
8357         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8358                 error "set stripe size on $MOUNT failed"
8359
8360         # new file created in $dir2 should inherit the new stripe size from
8361         # the filesystem default
8362         local file2=$dir2/$tfile-2
8363         touch $file2 || error "touch $file2 failed"
8364
8365         local file2_stripe_size=$($LFS getstripe -S $file2)
8366         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8367                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8368
8369         local dir3=$MOUNT/$tdir-3
8370         mkdir $dir3 || error "mkdir $dir3 failed"
8371         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8372         # the root layout, which is the actual default layout that will be used
8373         # when new files are created in $dir3.
8374         local dir3_layout=$(get_layout_param $dir3)
8375         local root_dir_layout=$(get_layout_param $MOUNT)
8376         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8377                 error "$dir3 should show the default layout from $MOUNT"
8378
8379         # set OST pool on root directory
8380         local pool=$TESTNAME
8381         pool_add $pool || error "add $pool failed"
8382         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8383                 error "add targets to $pool failed"
8384
8385         $LFS setstripe -p $pool $MOUNT ||
8386                 error "set OST pool on $MOUNT failed"
8387
8388         # new file created in $dir3 should inherit the pool from
8389         # the filesystem default
8390         local file3=$dir3/$tfile-3
8391         touch $file3 || error "touch $file3 failed"
8392
8393         local file3_pool=$($LFS getstripe -p $file3)
8394         [[ "$file3_pool" = "$pool" ]] ||
8395                 error "$file3 didn't inherit OST pool $pool"
8396
8397         local dir4=$MOUNT/$tdir-4
8398         mkdir $dir4 || error "mkdir $dir4 failed"
8399         local dir4_layout=$(get_layout_param $dir4)
8400         root_dir_layout=$(get_layout_param $MOUNT)
8401         echo "$LFS getstripe -d $dir4"
8402         $LFS getstripe -d $dir4
8403         echo "$LFS getstripe -d $MOUNT"
8404         $LFS getstripe -d $MOUNT
8405         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8406                 error "$dir4 should show the default layout from $MOUNT"
8407
8408         # new file created in $dir4 should inherit the pool from
8409         # the filesystem default
8410         local file4=$dir4/$tfile-4
8411         touch $file4 || error "touch $file4 failed"
8412
8413         local file4_pool=$($LFS getstripe -p $file4)
8414         [[ "$file4_pool" = "$pool" ]] ||
8415                 error "$file4 didn't inherit OST pool $pool"
8416
8417         # new subdirectory under non-root directory should inherit
8418         # the default layout from its parent directory
8419         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8420                 error "set directory layout on $dir4 failed"
8421
8422         local dir5=$dir4/$tdir-5
8423         mkdir $dir5 || error "mkdir $dir5 failed"
8424
8425         dir4_layout=$(get_layout_param $dir4)
8426         local dir5_layout=$(get_layout_param $dir5)
8427         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8428                 error "$dir5 should inherit the default layout from $dir4"
8429
8430         # though subdir under ROOT doesn't inherit default layout, but
8431         # its sub dir/file should be created with default layout.
8432         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8433         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8434                 skip "Need MDS version at least 2.12.59"
8435
8436         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8437         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8438         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8439
8440         if [ $default_lmv_hash == "none" ]; then
8441                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8442         else
8443                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8444                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8445         fi
8446
8447         $LFS setdirstripe -D -c 2 $MOUNT ||
8448                 error "setdirstripe -D -c 2 failed"
8449         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8450         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8451         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8452 }
8453 run_test 65n "don't inherit default layout from root for new subdirectories"
8454
8455 # bug 2543 - update blocks count on client
8456 test_66() {
8457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8458
8459         COUNT=${COUNT:-8}
8460         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8461         sync; sync_all_data; sync; sync_all_data
8462         cancel_lru_locks osc
8463         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8464         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8465 }
8466 run_test 66 "update inode blocks count on client ==============="
8467
8468 meminfo() {
8469         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8470 }
8471
8472 swap_used() {
8473         swapon -s | awk '($1 == "'$1'") { print $4 }'
8474 }
8475
8476 # bug5265, obdfilter oa2dentry return -ENOENT
8477 # #define OBD_FAIL_SRV_ENOENT 0x217
8478 test_69() {
8479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8480         remote_ost_nodsh && skip "remote OST with nodsh"
8481
8482         f="$DIR/$tfile"
8483         $LFS setstripe -c 1 -i 0 $f
8484
8485         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8486
8487         do_facet ost1 lctl set_param fail_loc=0x217
8488         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8489         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8490
8491         do_facet ost1 lctl set_param fail_loc=0
8492         $DIRECTIO write $f 0 2 || error "write error"
8493
8494         cancel_lru_locks osc
8495         $DIRECTIO read $f 0 1 || error "read error"
8496
8497         do_facet ost1 lctl set_param fail_loc=0x217
8498         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8499
8500         do_facet ost1 lctl set_param fail_loc=0
8501         rm -f $f
8502 }
8503 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8504
8505 test_71() {
8506         test_mkdir $DIR/$tdir
8507         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8508         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8509 }
8510 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8511
8512 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8514         [ "$RUNAS_ID" = "$UID" ] &&
8515                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8516         # Check that testing environment is properly set up. Skip if not
8517         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8518                 skip_env "User $RUNAS_ID does not exist - skipping"
8519
8520         touch $DIR/$tfile
8521         chmod 777 $DIR/$tfile
8522         chmod ug+s $DIR/$tfile
8523         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8524                 error "$RUNAS dd $DIR/$tfile failed"
8525         # See if we are still setuid/sgid
8526         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8527                 error "S/gid is not dropped on write"
8528         # Now test that MDS is updated too
8529         cancel_lru_locks mdc
8530         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8531                 error "S/gid is not dropped on MDS"
8532         rm -f $DIR/$tfile
8533 }
8534 run_test 72a "Test that remove suid works properly (bug5695) ===="
8535
8536 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8537         local perm
8538
8539         [ "$RUNAS_ID" = "$UID" ] &&
8540                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8541         [ "$RUNAS_ID" -eq 0 ] &&
8542                 skip_env "RUNAS_ID = 0 -- skipping"
8543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8544         # Check that testing environment is properly set up. Skip if not
8545         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8546                 skip_env "User $RUNAS_ID does not exist - skipping"
8547
8548         touch $DIR/${tfile}-f{g,u}
8549         test_mkdir $DIR/${tfile}-dg
8550         test_mkdir $DIR/${tfile}-du
8551         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8552         chmod g+s $DIR/${tfile}-{f,d}g
8553         chmod u+s $DIR/${tfile}-{f,d}u
8554         for perm in 777 2777 4777; do
8555                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8556                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8557                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8558                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8559         done
8560         true
8561 }
8562 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8563
8564 # bug 3462 - multiple simultaneous MDC requests
8565 test_73() {
8566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8567
8568         test_mkdir $DIR/d73-1
8569         test_mkdir $DIR/d73-2
8570         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8571         pid1=$!
8572
8573         lctl set_param fail_loc=0x80000129
8574         $MULTIOP $DIR/d73-1/f73-2 Oc &
8575         sleep 1
8576         lctl set_param fail_loc=0
8577
8578         $MULTIOP $DIR/d73-2/f73-3 Oc &
8579         pid3=$!
8580
8581         kill -USR1 $pid1
8582         wait $pid1 || return 1
8583
8584         sleep 25
8585
8586         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8587         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8588         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8589
8590         rm -rf $DIR/d73-*
8591 }
8592 run_test 73 "multiple MDC requests (should not deadlock)"
8593
8594 test_74a() { # bug 6149, 6184
8595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8596
8597         touch $DIR/f74a
8598         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8599         #
8600         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8601         # will spin in a tight reconnection loop
8602         $LCTL set_param fail_loc=0x8000030e
8603         # get any lock that won't be difficult - lookup works.
8604         ls $DIR/f74a
8605         $LCTL set_param fail_loc=0
8606         rm -f $DIR/f74a
8607         true
8608 }
8609 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8610
8611 test_74b() { # bug 13310
8612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8613
8614         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8615         #
8616         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8617         # will spin in a tight reconnection loop
8618         $LCTL set_param fail_loc=0x8000030e
8619         # get a "difficult" lock
8620         touch $DIR/f74b
8621         $LCTL set_param fail_loc=0
8622         rm -f $DIR/f74b
8623         true
8624 }
8625 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8626
8627 test_74c() {
8628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8629
8630         #define OBD_FAIL_LDLM_NEW_LOCK
8631         $LCTL set_param fail_loc=0x319
8632         touch $DIR/$tfile && error "touch successful"
8633         $LCTL set_param fail_loc=0
8634         true
8635 }
8636 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8637
8638 slab_lic=/sys/kernel/slab/lustre_inode_cache
8639 num_objects() {
8640         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
8641         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
8642                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
8643 }
8644
8645 test_76a() { # Now for b=20433, added originally in b=1443
8646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8647
8648         cancel_lru_locks osc
8649         # there may be some slab objects cached per core
8650         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8651         local before=$(num_objects)
8652         local count=$((512 * cpus))
8653         [ "$SLOW" = "no" ] && count=$((128 * cpus))
8654         local margin=$((count / 10))
8655         if [[ -f $slab_lic/aliases ]]; then
8656                 local aliases=$(cat $slab_lic/aliases)
8657                 (( aliases > 0 )) && margin=$((margin * aliases))
8658         fi
8659
8660         echo "before slab objects: $before"
8661         for i in $(seq $count); do
8662                 touch $DIR/$tfile
8663                 rm -f $DIR/$tfile
8664         done
8665         cancel_lru_locks osc
8666         local after=$(num_objects)
8667         echo "created: $count, after slab objects: $after"
8668         # shared slab counts are not very accurate, allow significant margin
8669         # the main goal is that the cache growth is not permanently > $count
8670         while (( after > before + margin )); do
8671                 sleep 1
8672                 after=$(num_objects)
8673                 wait=$((wait + 1))
8674                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8675                 if (( wait > 60 )); then
8676                         error "inode slab grew from $before+$margin to $after"
8677                 fi
8678         done
8679 }
8680 run_test 76a "confirm clients recycle inodes properly ===="
8681
8682 test_76b() {
8683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8684         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
8685
8686         local count=512
8687         local before=$(num_objects)
8688
8689         for i in $(seq $count); do
8690                 mkdir $DIR/$tdir
8691                 rmdir $DIR/$tdir
8692         done
8693
8694         local after=$(num_objects)
8695         local wait=0
8696
8697         while (( after > before )); do
8698                 sleep 1
8699                 after=$(num_objects)
8700                 wait=$((wait + 1))
8701                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8702                 if (( wait > 60 )); then
8703                         error "inode slab grew from $before to $after"
8704                 fi
8705         done
8706
8707         echo "slab objects before: $before, after: $after"
8708 }
8709 run_test 76b "confirm clients recycle directory inodes properly ===="
8710
8711 export ORIG_CSUM=""
8712 set_checksums()
8713 {
8714         # Note: in sptlrpc modes which enable its own bulk checksum, the
8715         # original crc32_le bulk checksum will be automatically disabled,
8716         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8717         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8718         # In this case set_checksums() will not be no-op, because sptlrpc
8719         # bulk checksum will be enabled all through the test.
8720
8721         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8722         lctl set_param -n osc.*.checksums $1
8723         return 0
8724 }
8725
8726 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8727                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8728 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8729                              tr -d [] | head -n1)}
8730 set_checksum_type()
8731 {
8732         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8733         rc=$?
8734         log "set checksum type to $1, rc = $rc"
8735         return $rc
8736 }
8737
8738 get_osc_checksum_type()
8739 {
8740         # arugment 1: OST name, like OST0000
8741         ost=$1
8742         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8743                         sed 's/.*\[\(.*\)\].*/\1/g')
8744         rc=$?
8745         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8746         echo $checksum_type
8747 }
8748
8749 F77_TMP=$TMP/f77-temp
8750 F77SZ=8
8751 setup_f77() {
8752         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8753                 error "error writing to $F77_TMP"
8754 }
8755
8756 test_77a() { # bug 10889
8757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8758         $GSS && skip_env "could not run with gss"
8759
8760         [ ! -f $F77_TMP ] && setup_f77
8761         set_checksums 1
8762         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8763         set_checksums 0
8764         rm -f $DIR/$tfile
8765 }
8766 run_test 77a "normal checksum read/write operation"
8767
8768 test_77b() { # bug 10889
8769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8770         $GSS && skip_env "could not run with gss"
8771
8772         [ ! -f $F77_TMP ] && setup_f77
8773         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8774         $LCTL set_param fail_loc=0x80000409
8775         set_checksums 1
8776
8777         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8778                 error "dd error: $?"
8779         $LCTL set_param fail_loc=0
8780
8781         for algo in $CKSUM_TYPES; do
8782                 cancel_lru_locks osc
8783                 set_checksum_type $algo
8784                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8785                 $LCTL set_param fail_loc=0x80000408
8786                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8787                 $LCTL set_param fail_loc=0
8788         done
8789         set_checksums 0
8790         set_checksum_type $ORIG_CSUM_TYPE
8791         rm -f $DIR/$tfile
8792 }
8793 run_test 77b "checksum error on client write, read"
8794
8795 cleanup_77c() {
8796         trap 0
8797         set_checksums 0
8798         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8799         $check_ost &&
8800                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8801         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8802         $check_ost && [ -n "$ost_file_prefix" ] &&
8803                 do_facet ost1 rm -f ${ost_file_prefix}\*
8804 }
8805
8806 test_77c() {
8807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8808         $GSS && skip_env "could not run with gss"
8809         remote_ost_nodsh && skip "remote OST with nodsh"
8810
8811         local bad1
8812         local osc_file_prefix
8813         local osc_file
8814         local check_ost=false
8815         local ost_file_prefix
8816         local ost_file
8817         local orig_cksum
8818         local dump_cksum
8819         local fid
8820
8821         # ensure corruption will occur on first OSS/OST
8822         $LFS setstripe -i 0 $DIR/$tfile
8823
8824         [ ! -f $F77_TMP ] && setup_f77
8825         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8826                 error "dd write error: $?"
8827         fid=$($LFS path2fid $DIR/$tfile)
8828
8829         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8830         then
8831                 check_ost=true
8832                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8833                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8834         else
8835                 echo "OSS do not support bulk pages dump upon error"
8836         fi
8837
8838         osc_file_prefix=$($LCTL get_param -n debug_path)
8839         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8840
8841         trap cleanup_77c EXIT
8842
8843         set_checksums 1
8844         # enable bulk pages dump upon error on Client
8845         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8846         # enable bulk pages dump upon error on OSS
8847         $check_ost &&
8848                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8849
8850         # flush Client cache to allow next read to reach OSS
8851         cancel_lru_locks osc
8852
8853         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8854         $LCTL set_param fail_loc=0x80000408
8855         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8856         $LCTL set_param fail_loc=0
8857
8858         rm -f $DIR/$tfile
8859
8860         # check cksum dump on Client
8861         osc_file=$(ls ${osc_file_prefix}*)
8862         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8863         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8864         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8865         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8866         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8867                      cksum)
8868         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8869         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8870                 error "dump content does not match on Client"
8871
8872         $check_ost || skip "No need to check cksum dump on OSS"
8873
8874         # check cksum dump on OSS
8875         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8876         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8877         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8878         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8879         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8880                 error "dump content does not match on OSS"
8881
8882         cleanup_77c
8883 }
8884 run_test 77c "checksum error on client read with debug"
8885
8886 test_77d() { # bug 10889
8887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8888         $GSS && skip_env "could not run with gss"
8889
8890         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8891         $LCTL set_param fail_loc=0x80000409
8892         set_checksums 1
8893         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8894                 error "direct write: rc=$?"
8895         $LCTL set_param fail_loc=0
8896         set_checksums 0
8897
8898         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8899         $LCTL set_param fail_loc=0x80000408
8900         set_checksums 1
8901         cancel_lru_locks osc
8902         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8903                 error "direct read: rc=$?"
8904         $LCTL set_param fail_loc=0
8905         set_checksums 0
8906 }
8907 run_test 77d "checksum error on OST direct write, read"
8908
8909 test_77f() { # bug 10889
8910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8911         $GSS && skip_env "could not run with gss"
8912
8913         set_checksums 1
8914         for algo in $CKSUM_TYPES; do
8915                 cancel_lru_locks osc
8916                 set_checksum_type $algo
8917                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8918                 $LCTL set_param fail_loc=0x409
8919                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8920                         error "direct write succeeded"
8921                 $LCTL set_param fail_loc=0
8922         done
8923         set_checksum_type $ORIG_CSUM_TYPE
8924         set_checksums 0
8925 }
8926 run_test 77f "repeat checksum error on write (expect error)"
8927
8928 test_77g() { # bug 10889
8929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8930         $GSS && skip_env "could not run with gss"
8931         remote_ost_nodsh && skip "remote OST with nodsh"
8932
8933         [ ! -f $F77_TMP ] && setup_f77
8934
8935         local file=$DIR/$tfile
8936         stack_trap "rm -f $file" EXIT
8937
8938         $LFS setstripe -c 1 -i 0 $file
8939         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8940         do_facet ost1 lctl set_param fail_loc=0x8000021a
8941         set_checksums 1
8942         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8943                 error "write error: rc=$?"
8944         do_facet ost1 lctl set_param fail_loc=0
8945         set_checksums 0
8946
8947         cancel_lru_locks osc
8948         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8949         do_facet ost1 lctl set_param fail_loc=0x8000021b
8950         set_checksums 1
8951         cmp $F77_TMP $file || error "file compare failed"
8952         do_facet ost1 lctl set_param fail_loc=0
8953         set_checksums 0
8954 }
8955 run_test 77g "checksum error on OST write, read"
8956
8957 test_77k() { # LU-10906
8958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8959         $GSS && skip_env "could not run with gss"
8960
8961         local cksum_param="osc.$FSNAME*.checksums"
8962         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8963         local checksum
8964         local i
8965
8966         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8967         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
8968         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
8969
8970         for i in 0 1; do
8971                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8972                         error "failed to set checksum=$i on MGS"
8973                 wait_update $HOSTNAME "$get_checksum" $i
8974                 #remount
8975                 echo "remount client, checksum should be $i"
8976                 remount_client $MOUNT || error "failed to remount client"
8977                 checksum=$(eval $get_checksum)
8978                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8979         done
8980         # remove persistent param to avoid races with checksum mountopt below
8981         do_facet mgs $LCTL set_param -P -d $cksum_param ||
8982                 error "failed to delete checksum on MGS"
8983
8984         for opt in "checksum" "nochecksum"; do
8985                 #remount with mount option
8986                 echo "remount client with option $opt, checksum should be $i"
8987                 umount_client $MOUNT || error "failed to umount client"
8988                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
8989                         error "failed to mount client with option '$opt'"
8990                 checksum=$(eval $get_checksum)
8991                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8992                 i=$((i - 1))
8993         done
8994
8995         remount_client $MOUNT || error "failed to remount client"
8996 }
8997 run_test 77k "enable/disable checksum correctly"
8998
8999 test_77l() {
9000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9001         $GSS && skip_env "could not run with gss"
9002
9003         set_checksums 1
9004         stack_trap "set_checksums $ORIG_CSUM" EXIT
9005         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9006
9007         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9008
9009         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9010         for algo in $CKSUM_TYPES; do
9011                 set_checksum_type $algo || error "fail to set checksum type $algo"
9012                 osc_algo=$(get_osc_checksum_type OST0000)
9013                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9014
9015                 # no locks, no reqs to let the connection idle
9016                 cancel_lru_locks osc
9017                 lru_resize_disable osc
9018                 wait_osc_import_state client ost1 IDLE
9019
9020                 # ensure ost1 is connected
9021                 stat $DIR/$tfile >/dev/null || error "can't stat"
9022                 wait_osc_import_state client ost1 FULL
9023
9024                 osc_algo=$(get_osc_checksum_type OST0000)
9025                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9026         done
9027         return 0
9028 }
9029 run_test 77l "preferred checksum type is remembered after reconnected"
9030
9031 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9032 rm -f $F77_TMP
9033 unset F77_TMP
9034
9035 cleanup_test_78() {
9036         trap 0
9037         rm -f $DIR/$tfile
9038 }
9039
9040 test_78() { # bug 10901
9041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9042         remote_ost || skip_env "local OST"
9043
9044         NSEQ=5
9045         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9046         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9047         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9048         echo "MemTotal: $MEMTOTAL"
9049
9050         # reserve 256MB of memory for the kernel and other running processes,
9051         # and then take 1/2 of the remaining memory for the read/write buffers.
9052         if [ $MEMTOTAL -gt 512 ] ;then
9053                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9054         else
9055                 # for those poor memory-starved high-end clusters...
9056                 MEMTOTAL=$((MEMTOTAL / 2))
9057         fi
9058         echo "Mem to use for directio: $MEMTOTAL"
9059
9060         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9061         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9062         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9063         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9064                 head -n1)
9065         echo "Smallest OST: $SMALLESTOST"
9066         [[ $SMALLESTOST -lt 10240 ]] &&
9067                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9068
9069         trap cleanup_test_78 EXIT
9070
9071         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9072                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9073
9074         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9075         echo "File size: $F78SIZE"
9076         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9077         for i in $(seq 1 $NSEQ); do
9078                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9079                 echo directIO rdwr round $i of $NSEQ
9080                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9081         done
9082
9083         cleanup_test_78
9084 }
9085 run_test 78 "handle large O_DIRECT writes correctly ============"
9086
9087 test_79() { # bug 12743
9088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9089
9090         wait_delete_completed
9091
9092         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9093         BKFREE=$(calc_osc_kbytes kbytesfree)
9094         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9095
9096         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9097         DFTOTAL=`echo $STRING | cut -d, -f1`
9098         DFUSED=`echo $STRING  | cut -d, -f2`
9099         DFAVAIL=`echo $STRING | cut -d, -f3`
9100         DFFREE=$(($DFTOTAL - $DFUSED))
9101
9102         ALLOWANCE=$((64 * $OSTCOUNT))
9103
9104         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9105            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9106                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9107         fi
9108         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9109            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9110                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9111         fi
9112         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9113            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9114                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9115         fi
9116 }
9117 run_test 79 "df report consistency check ======================="
9118
9119 test_80() { # bug 10718
9120         remote_ost_nodsh && skip "remote OST with nodsh"
9121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9122
9123         # relax strong synchronous semantics for slow backends like ZFS
9124         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9125                 local soc="obdfilter.*.sync_lock_cancel"
9126                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9127
9128                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9129                 if [ -z "$save" ]; then
9130                         soc="obdfilter.*.sync_on_lock_cancel"
9131                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9132                 fi
9133
9134                 if [ "$save" != "never" ]; then
9135                         local hosts=$(comma_list $(osts_nodes))
9136
9137                         do_nodes $hosts $LCTL set_param $soc=never
9138                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9139                 fi
9140         fi
9141
9142         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9143         sync; sleep 1; sync
9144         local before=$(date +%s)
9145         cancel_lru_locks osc
9146         local after=$(date +%s)
9147         local diff=$((after - before))
9148         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9149
9150         rm -f $DIR/$tfile
9151 }
9152 run_test 80 "Page eviction is equally fast at high offsets too"
9153
9154 test_81a() { # LU-456
9155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9156         remote_ost_nodsh && skip "remote OST with nodsh"
9157
9158         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9159         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9160         do_facet ost1 lctl set_param fail_loc=0x80000228
9161
9162         # write should trigger a retry and success
9163         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9164         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9165         RC=$?
9166         if [ $RC -ne 0 ] ; then
9167                 error "write should success, but failed for $RC"
9168         fi
9169 }
9170 run_test 81a "OST should retry write when get -ENOSPC ==============="
9171
9172 test_81b() { # LU-456
9173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9174         remote_ost_nodsh && skip "remote OST with nodsh"
9175
9176         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9177         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9178         do_facet ost1 lctl set_param fail_loc=0x228
9179
9180         # write should retry several times and return -ENOSPC finally
9181         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9182         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9183         RC=$?
9184         ENOSPC=28
9185         if [ $RC -ne $ENOSPC ] ; then
9186                 error "dd should fail for -ENOSPC, but succeed."
9187         fi
9188 }
9189 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9190
9191 test_99() {
9192         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9193
9194         test_mkdir $DIR/$tdir.cvsroot
9195         chown $RUNAS_ID $DIR/$tdir.cvsroot
9196
9197         cd $TMP
9198         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9199
9200         cd /etc/init.d
9201         # some versions of cvs import exit(1) when asked to import links or
9202         # files they can't read.  ignore those files.
9203         local toignore=$(find . -type l -printf '-I %f\n' -o \
9204                          ! -perm /4 -printf '-I %f\n')
9205         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9206                 $tdir.reposname vtag rtag
9207
9208         cd $DIR
9209         test_mkdir $DIR/$tdir.reposname
9210         chown $RUNAS_ID $DIR/$tdir.reposname
9211         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9212
9213         cd $DIR/$tdir.reposname
9214         $RUNAS touch foo99
9215         $RUNAS cvs add -m 'addmsg' foo99
9216         $RUNAS cvs update
9217         $RUNAS cvs commit -m 'nomsg' foo99
9218         rm -fr $DIR/$tdir.cvsroot
9219 }
9220 run_test 99 "cvs strange file/directory operations"
9221
9222 test_100() {
9223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9224         [[ "$NETTYPE" =~ tcp ]] ||
9225                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9226         remote_ost_nodsh && skip "remote OST with nodsh"
9227         remote_mds_nodsh && skip "remote MDS with nodsh"
9228         remote_servers ||
9229                 skip "useless for local single node setup"
9230
9231         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9232                 [ "$PROT" != "tcp" ] && continue
9233                 RPORT=$(echo $REMOTE | cut -d: -f2)
9234                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9235
9236                 rc=0
9237                 LPORT=`echo $LOCAL | cut -d: -f2`
9238                 if [ $LPORT -ge 1024 ]; then
9239                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9240                         netstat -tna
9241                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9242                 fi
9243         done
9244         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9245 }
9246 run_test 100 "check local port using privileged port ==========="
9247
9248 function get_named_value()
9249 {
9250     local tag
9251
9252     tag=$1
9253     while read ;do
9254         line=$REPLY
9255         case $line in
9256         $tag*)
9257             echo $line | sed "s/^$tag[ ]*//"
9258             break
9259             ;;
9260         esac
9261     done
9262 }
9263
9264 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9265                    awk '/^max_cached_mb/ { print $2 }')
9266
9267 cleanup_101a() {
9268         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9269         trap 0
9270 }
9271
9272 test_101a() {
9273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9274
9275         local s
9276         local discard
9277         local nreads=10000
9278         local cache_limit=32
9279
9280         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9281         trap cleanup_101a EXIT
9282         $LCTL set_param -n llite.*.read_ahead_stats 0
9283         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9284
9285         #
9286         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9287         #
9288         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9289         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9290
9291         discard=0
9292         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9293                 get_named_value 'read but discarded' | cut -d" " -f1); do
9294                         discard=$(($discard + $s))
9295         done
9296         cleanup_101a
9297
9298         $LCTL get_param osc.*-osc*.rpc_stats
9299         $LCTL get_param llite.*.read_ahead_stats
9300
9301         # Discard is generally zero, but sometimes a few random reads line up
9302         # and trigger larger readahead, which is wasted & leads to discards.
9303         if [[ $(($discard)) -gt $nreads ]]; then
9304                 error "too many ($discard) discarded pages"
9305         fi
9306         rm -f $DIR/$tfile || true
9307 }
9308 run_test 101a "check read-ahead for random reads"
9309
9310 setup_test101bc() {
9311         test_mkdir $DIR/$tdir
9312         local ssize=$1
9313         local FILE_LENGTH=$2
9314         STRIPE_OFFSET=0
9315
9316         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9317
9318         local list=$(comma_list $(osts_nodes))
9319         set_osd_param $list '' read_cache_enable 0
9320         set_osd_param $list '' writethrough_cache_enable 0
9321
9322         trap cleanup_test101bc EXIT
9323         # prepare the read-ahead file
9324         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9325
9326         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9327                                 count=$FILE_SIZE_MB 2> /dev/null
9328
9329 }
9330
9331 cleanup_test101bc() {
9332         trap 0
9333         rm -rf $DIR/$tdir
9334         rm -f $DIR/$tfile
9335
9336         local list=$(comma_list $(osts_nodes))
9337         set_osd_param $list '' read_cache_enable 1
9338         set_osd_param $list '' writethrough_cache_enable 1
9339 }
9340
9341 calc_total() {
9342         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9343 }
9344
9345 ra_check_101() {
9346         local READ_SIZE=$1
9347         local STRIPE_SIZE=$2
9348         local FILE_LENGTH=$3
9349         local RA_INC=1048576
9350         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9351         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9352                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9353         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9354                         get_named_value 'read but discarded' |
9355                         cut -d" " -f1 | calc_total)
9356         if [[ $DISCARD -gt $discard_limit ]]; then
9357                 $LCTL get_param llite.*.read_ahead_stats
9358                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9359         else
9360                 echo "Read-ahead success for size ${READ_SIZE}"
9361         fi
9362 }
9363
9364 test_101b() {
9365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9366         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9367
9368         local STRIPE_SIZE=1048576
9369         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9370
9371         if [ $SLOW == "yes" ]; then
9372                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9373         else
9374                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9375         fi
9376
9377         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9378
9379         # prepare the read-ahead file
9380         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9381         cancel_lru_locks osc
9382         for BIDX in 2 4 8 16 32 64 128 256
9383         do
9384                 local BSIZE=$((BIDX*4096))
9385                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9386                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9387                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9388                 $LCTL set_param -n llite.*.read_ahead_stats 0
9389                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9390                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9391                 cancel_lru_locks osc
9392                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9393         done
9394         cleanup_test101bc
9395         true
9396 }
9397 run_test 101b "check stride-io mode read-ahead ================="
9398
9399 test_101c() {
9400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9401
9402         local STRIPE_SIZE=1048576
9403         local FILE_LENGTH=$((STRIPE_SIZE*100))
9404         local nreads=10000
9405         local rsize=65536
9406         local osc_rpc_stats
9407
9408         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9409
9410         cancel_lru_locks osc
9411         $LCTL set_param osc.*.rpc_stats 0
9412         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9413         $LCTL get_param osc.*.rpc_stats
9414         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9415                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9416                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9417                 local size
9418
9419                 if [ $lines -le 20 ]; then
9420                         echo "continue debug"
9421                         continue
9422                 fi
9423                 for size in 1 2 4 8; do
9424                         local rpc=$(echo "$stats" |
9425                                     awk '($1 == "'$size':") {print $2; exit; }')
9426                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9427                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9428                 done
9429                 echo "$osc_rpc_stats check passed!"
9430         done
9431         cleanup_test101bc
9432         true
9433 }
9434 run_test 101c "check stripe_size aligned read-ahead ================="
9435
9436 test_101d() {
9437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9438
9439         local file=$DIR/$tfile
9440         local sz_MB=${FILESIZE_101d:-80}
9441         local ra_MB=${READAHEAD_MB:-40}
9442
9443         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9444         [ $free_MB -lt $sz_MB ] &&
9445                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9446
9447         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9448         $LFS setstripe -c -1 $file || error "setstripe failed"
9449
9450         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9451         echo Cancel LRU locks on lustre client to flush the client cache
9452         cancel_lru_locks osc
9453
9454         echo Disable read-ahead
9455         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9456         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9457         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9458         $LCTL get_param -n llite.*.max_read_ahead_mb
9459
9460         echo "Reading the test file $file with read-ahead disabled"
9461         local sz_KB=$((sz_MB * 1024 / 4))
9462         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9463         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9464         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9465                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9466
9467         echo "Cancel LRU locks on lustre client to flush the client cache"
9468         cancel_lru_locks osc
9469         echo Enable read-ahead with ${ra_MB}MB
9470         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9471
9472         echo "Reading the test file $file with read-ahead enabled"
9473         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9474                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9475
9476         echo "read-ahead disabled time read $raOFF"
9477         echo "read-ahead enabled time read $raON"
9478
9479         rm -f $file
9480         wait_delete_completed
9481
9482         # use awk for this check instead of bash because it handles decimals
9483         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9484                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9485 }
9486 run_test 101d "file read with and without read-ahead enabled"
9487
9488 test_101e() {
9489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9490
9491         local file=$DIR/$tfile
9492         local size_KB=500  #KB
9493         local count=100
9494         local bsize=1024
9495
9496         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9497         local need_KB=$((count * size_KB))
9498         [[ $free_KB -le $need_KB ]] &&
9499                 skip_env "Need free space $need_KB, have $free_KB"
9500
9501         echo "Creating $count ${size_KB}K test files"
9502         for ((i = 0; i < $count; i++)); do
9503                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9504         done
9505
9506         echo "Cancel LRU locks on lustre client to flush the client cache"
9507         cancel_lru_locks $OSC
9508
9509         echo "Reset readahead stats"
9510         $LCTL set_param -n llite.*.read_ahead_stats 0
9511
9512         for ((i = 0; i < $count; i++)); do
9513                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9514         done
9515
9516         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9517                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9518
9519         for ((i = 0; i < $count; i++)); do
9520                 rm -rf $file.$i 2>/dev/null
9521         done
9522
9523         #10000 means 20% reads are missing in readahead
9524         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9525 }
9526 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9527
9528 test_101f() {
9529         which iozone || skip_env "no iozone installed"
9530
9531         local old_debug=$($LCTL get_param debug)
9532         old_debug=${old_debug#*=}
9533         $LCTL set_param debug="reada mmap"
9534
9535         # create a test file
9536         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9537
9538         echo Cancel LRU locks on lustre client to flush the client cache
9539         cancel_lru_locks osc
9540
9541         echo Reset readahead stats
9542         $LCTL set_param -n llite.*.read_ahead_stats 0
9543
9544         echo mmap read the file with small block size
9545         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9546                 > /dev/null 2>&1
9547
9548         echo checking missing pages
9549         $LCTL get_param llite.*.read_ahead_stats
9550         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9551                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9552
9553         $LCTL set_param debug="$old_debug"
9554         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9555         rm -f $DIR/$tfile
9556 }
9557 run_test 101f "check mmap read performance"
9558
9559 test_101g_brw_size_test() {
9560         local mb=$1
9561         local pages=$((mb * 1048576 / PAGE_SIZE))
9562         local file=$DIR/$tfile
9563
9564         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9565                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9566         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9567                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9568                         return 2
9569         done
9570
9571         stack_trap "rm -f $file" EXIT
9572         $LCTL set_param -n osc.*.rpc_stats=0
9573
9574         # 10 RPCs should be enough for the test
9575         local count=10
9576         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9577                 { error "dd write ${mb} MB blocks failed"; return 3; }
9578         cancel_lru_locks osc
9579         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9580                 { error "dd write ${mb} MB blocks failed"; return 4; }
9581
9582         # calculate number of full-sized read and write RPCs
9583         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9584                 sed -n '/pages per rpc/,/^$/p' |
9585                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9586                 END { print reads,writes }'))
9587         # allow one extra full-sized read RPC for async readahead
9588         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9589                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9590         [[ ${rpcs[1]} == $count ]] ||
9591                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9592 }
9593
9594 test_101g() {
9595         remote_ost_nodsh && skip "remote OST with nodsh"
9596
9597         local rpcs
9598         local osts=$(get_facets OST)
9599         local list=$(comma_list $(osts_nodes))
9600         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9601         local brw_size="obdfilter.*.brw_size"
9602
9603         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9604
9605         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9606
9607         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9608                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9609                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9610            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9611                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9612                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9613
9614                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9615                         suffix="M"
9616
9617                 if [[ $orig_mb -lt 16 ]]; then
9618                         save_lustre_params $osts "$brw_size" > $p
9619                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9620                                 error "set 16MB RPC size failed"
9621
9622                         echo "remount client to enable new RPC size"
9623                         remount_client $MOUNT || error "remount_client failed"
9624                 fi
9625
9626                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9627                 # should be able to set brw_size=12, but no rpc_stats for that
9628                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9629         fi
9630
9631         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9632
9633         if [[ $orig_mb -lt 16 ]]; then
9634                 restore_lustre_params < $p
9635                 remount_client $MOUNT || error "remount_client restore failed"
9636         fi
9637
9638         rm -f $p $DIR/$tfile
9639 }
9640 run_test 101g "Big bulk(4/16 MiB) readahead"
9641
9642 test_101h() {
9643         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9644
9645         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9646                 error "dd 70M file failed"
9647         echo Cancel LRU locks on lustre client to flush the client cache
9648         cancel_lru_locks osc
9649
9650         echo "Reset readahead stats"
9651         $LCTL set_param -n llite.*.read_ahead_stats 0
9652
9653         echo "Read 10M of data but cross 64M bundary"
9654         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9655         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9656                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9657         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9658         rm -f $p $DIR/$tfile
9659 }
9660 run_test 101h "Readahead should cover current read window"
9661
9662 test_101i() {
9663         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9664                 error "dd 10M file failed"
9665
9666         local max_per_file_mb=$($LCTL get_param -n \
9667                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9668         cancel_lru_locks osc
9669         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9670         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9671                 error "set max_read_ahead_per_file_mb to 1 failed"
9672
9673         echo "Reset readahead stats"
9674         $LCTL set_param llite.*.read_ahead_stats=0
9675
9676         dd if=$DIR/$tfile of=/dev/null bs=2M
9677
9678         $LCTL get_param llite.*.read_ahead_stats
9679         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9680                      awk '/misses/ { print $2 }')
9681         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9682         rm -f $DIR/$tfile
9683 }
9684 run_test 101i "allow current readahead to exceed reservation"
9685
9686 test_101j() {
9687         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9688                 error "setstripe $DIR/$tfile failed"
9689         local file_size=$((1048576 * 16))
9690         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9691         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9692
9693         echo Disable read-ahead
9694         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9695
9696         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9697         for blk in $PAGE_SIZE 1048576 $file_size; do
9698                 cancel_lru_locks osc
9699                 echo "Reset readahead stats"
9700                 $LCTL set_param -n llite.*.read_ahead_stats=0
9701                 local count=$(($file_size / $blk))
9702                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9703                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9704                              get_named_value 'failed to fast read' |
9705                              cut -d" " -f1 | calc_total)
9706                 $LCTL get_param -n llite.*.read_ahead_stats
9707                 [ $miss -eq $count ] || error "expected $count got $miss"
9708         done
9709
9710         rm -f $p $DIR/$tfile
9711 }
9712 run_test 101j "A complete read block should be submitted when no RA"
9713
9714 setup_test102() {
9715         test_mkdir $DIR/$tdir
9716         chown $RUNAS_ID $DIR/$tdir
9717         STRIPE_SIZE=65536
9718         STRIPE_OFFSET=1
9719         STRIPE_COUNT=$OSTCOUNT
9720         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9721
9722         trap cleanup_test102 EXIT
9723         cd $DIR
9724         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9725         cd $DIR/$tdir
9726         for num in 1 2 3 4; do
9727                 for count in $(seq 1 $STRIPE_COUNT); do
9728                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9729                                 local size=`expr $STRIPE_SIZE \* $num`
9730                                 local file=file"$num-$idx-$count"
9731                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9732                         done
9733                 done
9734         done
9735
9736         cd $DIR
9737         $1 tar cf $TMP/f102.tar $tdir --xattrs
9738 }
9739
9740 cleanup_test102() {
9741         trap 0
9742         rm -f $TMP/f102.tar
9743         rm -rf $DIR/d0.sanity/d102
9744 }
9745
9746 test_102a() {
9747         [ "$UID" != 0 ] && skip "must run as root"
9748         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9749                 skip_env "must have user_xattr"
9750
9751         [ -z "$(which setfattr 2>/dev/null)" ] &&
9752                 skip_env "could not find setfattr"
9753
9754         local testfile=$DIR/$tfile
9755
9756         touch $testfile
9757         echo "set/get xattr..."
9758         setfattr -n trusted.name1 -v value1 $testfile ||
9759                 error "setfattr -n trusted.name1=value1 $testfile failed"
9760         getfattr -n trusted.name1 $testfile 2> /dev/null |
9761           grep "trusted.name1=.value1" ||
9762                 error "$testfile missing trusted.name1=value1"
9763
9764         setfattr -n user.author1 -v author1 $testfile ||
9765                 error "setfattr -n user.author1=author1 $testfile failed"
9766         getfattr -n user.author1 $testfile 2> /dev/null |
9767           grep "user.author1=.author1" ||
9768                 error "$testfile missing trusted.author1=author1"
9769
9770         echo "listxattr..."
9771         setfattr -n trusted.name2 -v value2 $testfile ||
9772                 error "$testfile unable to set trusted.name2"
9773         setfattr -n trusted.name3 -v value3 $testfile ||
9774                 error "$testfile unable to set trusted.name3"
9775         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9776             grep "trusted.name" | wc -l) -eq 3 ] ||
9777                 error "$testfile missing 3 trusted.name xattrs"
9778
9779         setfattr -n user.author2 -v author2 $testfile ||
9780                 error "$testfile unable to set user.author2"
9781         setfattr -n user.author3 -v author3 $testfile ||
9782                 error "$testfile unable to set user.author3"
9783         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9784             grep "user.author" | wc -l) -eq 3 ] ||
9785                 error "$testfile missing 3 user.author xattrs"
9786
9787         echo "remove xattr..."
9788         setfattr -x trusted.name1 $testfile ||
9789                 error "$testfile error deleting trusted.name1"
9790         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9791                 error "$testfile did not delete trusted.name1 xattr"
9792
9793         setfattr -x user.author1 $testfile ||
9794                 error "$testfile error deleting user.author1"
9795         echo "set lustre special xattr ..."
9796         $LFS setstripe -c1 $testfile
9797         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9798                 awk -F "=" '/trusted.lov/ { print $2 }' )
9799         setfattr -n "trusted.lov" -v $lovea $testfile ||
9800                 error "$testfile doesn't ignore setting trusted.lov again"
9801         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9802                 error "$testfile allow setting invalid trusted.lov"
9803         rm -f $testfile
9804 }
9805 run_test 102a "user xattr test =================================="
9806
9807 check_102b_layout() {
9808         local layout="$*"
9809         local testfile=$DIR/$tfile
9810
9811         echo "test layout '$layout'"
9812         $LFS setstripe $layout $testfile || error "setstripe failed"
9813         $LFS getstripe -y $testfile
9814
9815         echo "get/set/list trusted.lov xattr ..." # b=10930
9816         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
9817         [[ "$value" =~ "trusted.lov" ]] ||
9818                 error "can't get trusted.lov from $testfile"
9819         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
9820                 error "getstripe failed"
9821
9822         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
9823
9824         value=$(cut -d= -f2 <<<$value)
9825         # LU-13168: truncated xattr should fail if short lov_user_md header
9826         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
9827                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
9828         for len in $lens; do
9829                 echo "setfattr $len $testfile.2"
9830                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
9831                         [ $len -lt 66 ] && error "short xattr len=$len worked"
9832         done
9833         local stripe_size=$($LFS getstripe -S $testfile.2)
9834         local stripe_count=$($LFS getstripe -c $testfile.2)
9835         [[ $stripe_size -eq 65536 ]] ||
9836                 error "stripe size $stripe_size != 65536"
9837         [[ $stripe_count -eq $stripe_count_orig ]] ||
9838                 error "stripe count $stripe_count != $stripe_count_orig"
9839         rm $testfile $testfile.2
9840 }
9841
9842 test_102b() {
9843         [ -z "$(which setfattr 2>/dev/null)" ] &&
9844                 skip_env "could not find setfattr"
9845         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9846
9847         # check plain layout
9848         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
9849
9850         # and also check composite layout
9851         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
9852
9853 }
9854 run_test 102b "getfattr/setfattr for trusted.lov EAs"
9855
9856 test_102c() {
9857         [ -z "$(which setfattr 2>/dev/null)" ] &&
9858                 skip_env "could not find setfattr"
9859         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9860
9861         # b10930: get/set/list lustre.lov xattr
9862         echo "get/set/list lustre.lov xattr ..."
9863         test_mkdir $DIR/$tdir
9864         chown $RUNAS_ID $DIR/$tdir
9865         local testfile=$DIR/$tdir/$tfile
9866         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9867                 error "setstripe failed"
9868         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9869                 error "getstripe failed"
9870         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9871         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9872
9873         local testfile2=${testfile}2
9874         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9875                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9876
9877         $RUNAS $MCREATE $testfile2
9878         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9879         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9880         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9881         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9882         [ $stripe_count -eq $STRIPECOUNT ] ||
9883                 error "stripe count $stripe_count != $STRIPECOUNT"
9884 }
9885 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9886
9887 compare_stripe_info1() {
9888         local stripe_index_all_zero=true
9889
9890         for num in 1 2 3 4; do
9891                 for count in $(seq 1 $STRIPE_COUNT); do
9892                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9893                                 local size=$((STRIPE_SIZE * num))
9894                                 local file=file"$num-$offset-$count"
9895                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9896                                 [[ $stripe_size -ne $size ]] &&
9897                                     error "$file: size $stripe_size != $size"
9898                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9899                                 # allow fewer stripes to be created, ORI-601
9900                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9901                                     error "$file: count $stripe_count != $count"
9902                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9903                                 [[ $stripe_index -ne 0 ]] &&
9904                                         stripe_index_all_zero=false
9905                         done
9906                 done
9907         done
9908         $stripe_index_all_zero &&
9909                 error "all files are being extracted starting from OST index 0"
9910         return 0
9911 }
9912
9913 have_xattrs_include() {
9914         tar --help | grep -q xattrs-include &&
9915                 echo --xattrs-include="lustre.*"
9916 }
9917
9918 test_102d() {
9919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9920         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9921
9922         XINC=$(have_xattrs_include)
9923         setup_test102
9924         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9925         cd $DIR/$tdir/$tdir
9926         compare_stripe_info1
9927 }
9928 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9929
9930 test_102f() {
9931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9932         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9933
9934         XINC=$(have_xattrs_include)
9935         setup_test102
9936         test_mkdir $DIR/$tdir.restore
9937         cd $DIR
9938         tar cf - --xattrs $tdir | tar xf - \
9939                 -C $DIR/$tdir.restore --xattrs $XINC
9940         cd $DIR/$tdir.restore/$tdir
9941         compare_stripe_info1
9942 }
9943 run_test 102f "tar copy files, not keep osts"
9944
9945 grow_xattr() {
9946         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9947                 skip "must have user_xattr"
9948         [ -z "$(which setfattr 2>/dev/null)" ] &&
9949                 skip_env "could not find setfattr"
9950         [ -z "$(which getfattr 2>/dev/null)" ] &&
9951                 skip_env "could not find getfattr"
9952
9953         local xsize=${1:-1024}  # in bytes
9954         local file=$DIR/$tfile
9955         local value="$(generate_string $xsize)"
9956         local xbig=trusted.big
9957         local toobig=$2
9958
9959         touch $file
9960         log "save $xbig on $file"
9961         if [ -z "$toobig" ]
9962         then
9963                 setfattr -n $xbig -v $value $file ||
9964                         error "saving $xbig on $file failed"
9965         else
9966                 setfattr -n $xbig -v $value $file &&
9967                         error "saving $xbig on $file succeeded"
9968                 return 0
9969         fi
9970
9971         local orig=$(get_xattr_value $xbig $file)
9972         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9973
9974         local xsml=trusted.sml
9975         log "save $xsml on $file"
9976         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
9977
9978         local new=$(get_xattr_value $xbig $file)
9979         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
9980
9981         log "grow $xsml on $file"
9982         setfattr -n $xsml -v "$value" $file ||
9983                 error "growing $xsml on $file failed"
9984
9985         new=$(get_xattr_value $xbig $file)
9986         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
9987         log "$xbig still valid after growing $xsml"
9988
9989         rm -f $file
9990 }
9991
9992 test_102h() { # bug 15777
9993         grow_xattr 1024
9994 }
9995 run_test 102h "grow xattr from inside inode to external block"
9996
9997 test_102ha() {
9998         large_xattr_enabled || skip_env "ea_inode feature disabled"
9999
10000         echo "setting xattr of max xattr size: $(max_xattr_size)"
10001         grow_xattr $(max_xattr_size)
10002
10003         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10004         echo "This should fail:"
10005         grow_xattr $(($(max_xattr_size) + 10)) 1
10006 }
10007 run_test 102ha "grow xattr from inside inode to external inode"
10008
10009 test_102i() { # bug 17038
10010         [ -z "$(which getfattr 2>/dev/null)" ] &&
10011                 skip "could not find getfattr"
10012
10013         touch $DIR/$tfile
10014         ln -s $DIR/$tfile $DIR/${tfile}link
10015         getfattr -n trusted.lov $DIR/$tfile ||
10016                 error "lgetxattr on $DIR/$tfile failed"
10017         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10018                 grep -i "no such attr" ||
10019                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10020         rm -f $DIR/$tfile $DIR/${tfile}link
10021 }
10022 run_test 102i "lgetxattr test on symbolic link ============"
10023
10024 test_102j() {
10025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10026         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10027
10028         XINC=$(have_xattrs_include)
10029         setup_test102 "$RUNAS"
10030         chown $RUNAS_ID $DIR/$tdir
10031         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10032         cd $DIR/$tdir/$tdir
10033         compare_stripe_info1 "$RUNAS"
10034 }
10035 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10036
10037 test_102k() {
10038         [ -z "$(which setfattr 2>/dev/null)" ] &&
10039                 skip "could not find setfattr"
10040
10041         touch $DIR/$tfile
10042         # b22187 just check that does not crash for regular file.
10043         setfattr -n trusted.lov $DIR/$tfile
10044         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10045         local test_kdir=$DIR/$tdir
10046         test_mkdir $test_kdir
10047         local default_size=$($LFS getstripe -S $test_kdir)
10048         local default_count=$($LFS getstripe -c $test_kdir)
10049         local default_offset=$($LFS getstripe -i $test_kdir)
10050         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10051                 error 'dir setstripe failed'
10052         setfattr -n trusted.lov $test_kdir
10053         local stripe_size=$($LFS getstripe -S $test_kdir)
10054         local stripe_count=$($LFS getstripe -c $test_kdir)
10055         local stripe_offset=$($LFS getstripe -i $test_kdir)
10056         [ $stripe_size -eq $default_size ] ||
10057                 error "stripe size $stripe_size != $default_size"
10058         [ $stripe_count -eq $default_count ] ||
10059                 error "stripe count $stripe_count != $default_count"
10060         [ $stripe_offset -eq $default_offset ] ||
10061                 error "stripe offset $stripe_offset != $default_offset"
10062         rm -rf $DIR/$tfile $test_kdir
10063 }
10064 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10065
10066 test_102l() {
10067         [ -z "$(which getfattr 2>/dev/null)" ] &&
10068                 skip "could not find getfattr"
10069
10070         # LU-532 trusted. xattr is invisible to non-root
10071         local testfile=$DIR/$tfile
10072
10073         touch $testfile
10074
10075         echo "listxattr as user..."
10076         chown $RUNAS_ID $testfile
10077         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10078             grep -q "trusted" &&
10079                 error "$testfile trusted xattrs are user visible"
10080
10081         return 0;
10082 }
10083 run_test 102l "listxattr size test =================================="
10084
10085 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10086         local path=$DIR/$tfile
10087         touch $path
10088
10089         listxattr_size_check $path || error "listattr_size_check $path failed"
10090 }
10091 run_test 102m "Ensure listxattr fails on small bufffer ========"
10092
10093 cleanup_test102
10094
10095 getxattr() { # getxattr path name
10096         # Return the base64 encoding of the value of xattr name on path.
10097         local path=$1
10098         local name=$2
10099
10100         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10101         # file: $path
10102         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10103         #
10104         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10105
10106         getfattr --absolute-names --encoding=base64 --name=$name $path |
10107                 awk -F= -v name=$name '$1 == name {
10108                         print substr($0, index($0, "=") + 1);
10109         }'
10110 }
10111
10112 test_102n() { # LU-4101 mdt: protect internal xattrs
10113         [ -z "$(which setfattr 2>/dev/null)" ] &&
10114                 skip "could not find setfattr"
10115         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10116         then
10117                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10118         fi
10119
10120         local file0=$DIR/$tfile.0
10121         local file1=$DIR/$tfile.1
10122         local xattr0=$TMP/$tfile.0
10123         local xattr1=$TMP/$tfile.1
10124         local namelist="lov lma lmv link fid version som hsm"
10125         local name
10126         local value
10127
10128         rm -rf $file0 $file1 $xattr0 $xattr1
10129         touch $file0 $file1
10130
10131         # Get 'before' xattrs of $file1.
10132         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10133
10134         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10135                 namelist+=" lfsck_namespace"
10136         for name in $namelist; do
10137                 # Try to copy xattr from $file0 to $file1.
10138                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10139
10140                 setfattr --name=trusted.$name --value="$value" $file1 ||
10141                         error "setxattr 'trusted.$name' failed"
10142
10143                 # Try to set a garbage xattr.
10144                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10145
10146                 if [[ x$name == "xlov" ]]; then
10147                         setfattr --name=trusted.lov --value="$value" $file1 &&
10148                         error "setxattr invalid 'trusted.lov' success"
10149                 else
10150                         setfattr --name=trusted.$name --value="$value" $file1 ||
10151                                 error "setxattr invalid 'trusted.$name' failed"
10152                 fi
10153
10154                 # Try to remove the xattr from $file1. We don't care if this
10155                 # appears to succeed or fail, we just don't want there to be
10156                 # any changes or crashes.
10157                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10158         done
10159
10160         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10161         then
10162                 name="lfsck_ns"
10163                 # Try to copy xattr from $file0 to $file1.
10164                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10165
10166                 setfattr --name=trusted.$name --value="$value" $file1 ||
10167                         error "setxattr 'trusted.$name' failed"
10168
10169                 # Try to set a garbage xattr.
10170                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10171
10172                 setfattr --name=trusted.$name --value="$value" $file1 ||
10173                         error "setxattr 'trusted.$name' failed"
10174
10175                 # Try to remove the xattr from $file1. We don't care if this
10176                 # appears to succeed or fail, we just don't want there to be
10177                 # any changes or crashes.
10178                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10179         fi
10180
10181         # Get 'after' xattrs of file1.
10182         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10183
10184         if ! diff $xattr0 $xattr1; then
10185                 error "before and after xattrs of '$file1' differ"
10186         fi
10187
10188         rm -rf $file0 $file1 $xattr0 $xattr1
10189
10190         return 0
10191 }
10192 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10193
10194 test_102p() { # LU-4703 setxattr did not check ownership
10195         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10196                 skip "MDS needs to be at least 2.5.56"
10197
10198         local testfile=$DIR/$tfile
10199
10200         touch $testfile
10201
10202         echo "setfacl as user..."
10203         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10204         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10205
10206         echo "setfattr as user..."
10207         setfacl -m "u:$RUNAS_ID:---" $testfile
10208         $RUNAS setfattr -x system.posix_acl_access $testfile
10209         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10210 }
10211 run_test 102p "check setxattr(2) correctly fails without permission"
10212
10213 test_102q() {
10214         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10215                 skip "MDS needs to be at least 2.6.92"
10216
10217         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10218 }
10219 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10220
10221 test_102r() {
10222         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10223                 skip "MDS needs to be at least 2.6.93"
10224
10225         touch $DIR/$tfile || error "touch"
10226         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10227         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10228         rm $DIR/$tfile || error "rm"
10229
10230         #normal directory
10231         mkdir -p $DIR/$tdir || error "mkdir"
10232         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10233         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10234         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10235                 error "$testfile error deleting user.author1"
10236         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10237                 grep "user.$(basename $tdir)" &&
10238                 error "$tdir did not delete user.$(basename $tdir)"
10239         rmdir $DIR/$tdir || error "rmdir"
10240
10241         #striped directory
10242         test_mkdir $DIR/$tdir
10243         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10244         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10245         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10246                 error "$testfile error deleting user.author1"
10247         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10248                 grep "user.$(basename $tdir)" &&
10249                 error "$tdir did not delete user.$(basename $tdir)"
10250         rmdir $DIR/$tdir || error "rm striped dir"
10251 }
10252 run_test 102r "set EAs with empty values"
10253
10254 test_102s() {
10255         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10256                 skip "MDS needs to be at least 2.11.52"
10257
10258         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10259
10260         save_lustre_params client "llite.*.xattr_cache" > $save
10261
10262         for cache in 0 1; do
10263                 lctl set_param llite.*.xattr_cache=$cache
10264
10265                 rm -f $DIR/$tfile
10266                 touch $DIR/$tfile || error "touch"
10267                 for prefix in lustre security system trusted user; do
10268                         # Note getxattr() may fail with 'Operation not
10269                         # supported' or 'No such attribute' depending
10270                         # on prefix and cache.
10271                         getfattr -n $prefix.n102s $DIR/$tfile &&
10272                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10273                 done
10274         done
10275
10276         restore_lustre_params < $save
10277 }
10278 run_test 102s "getting nonexistent xattrs should fail"
10279
10280 test_102t() {
10281         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10282                 skip "MDS needs to be at least 2.11.52"
10283
10284         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10285
10286         save_lustre_params client "llite.*.xattr_cache" > $save
10287
10288         for cache in 0 1; do
10289                 lctl set_param llite.*.xattr_cache=$cache
10290
10291                 for buf_size in 0 256; do
10292                         rm -f $DIR/$tfile
10293                         touch $DIR/$tfile || error "touch"
10294                         setfattr -n user.multiop $DIR/$tfile
10295                         $MULTIOP $DIR/$tfile oa$buf_size ||
10296                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10297                 done
10298         done
10299
10300         restore_lustre_params < $save
10301 }
10302 run_test 102t "zero length xattr values handled correctly"
10303
10304 run_acl_subtest()
10305 {
10306     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10307     return $?
10308 }
10309
10310 test_103a() {
10311         [ "$UID" != 0 ] && skip "must run as root"
10312         $GSS && skip_env "could not run under gss"
10313         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10314                 skip_env "must have acl enabled"
10315         [ -z "$(which setfacl 2>/dev/null)" ] &&
10316                 skip_env "could not find setfacl"
10317         remote_mds_nodsh && skip "remote MDS with nodsh"
10318
10319         gpasswd -a daemon bin                           # LU-5641
10320         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10321
10322         declare -a identity_old
10323
10324         for num in $(seq $MDSCOUNT); do
10325                 switch_identity $num true || identity_old[$num]=$?
10326         done
10327
10328         SAVE_UMASK=$(umask)
10329         umask 0022
10330         mkdir -p $DIR/$tdir
10331         cd $DIR/$tdir
10332
10333         echo "performing cp ..."
10334         run_acl_subtest cp || error "run_acl_subtest cp failed"
10335         echo "performing getfacl-noacl..."
10336         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10337         echo "performing misc..."
10338         run_acl_subtest misc || error  "misc test failed"
10339         echo "performing permissions..."
10340         run_acl_subtest permissions || error "permissions failed"
10341         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10342         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10343                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10344                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10345         then
10346                 echo "performing permissions xattr..."
10347                 run_acl_subtest permissions_xattr ||
10348                         error "permissions_xattr failed"
10349         fi
10350         echo "performing setfacl..."
10351         run_acl_subtest setfacl || error  "setfacl test failed"
10352
10353         # inheritance test got from HP
10354         echo "performing inheritance..."
10355         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10356         chmod +x make-tree || error "chmod +x failed"
10357         run_acl_subtest inheritance || error "inheritance test failed"
10358         rm -f make-tree
10359
10360         echo "LU-974 ignore umask when acl is enabled..."
10361         run_acl_subtest 974 || error "LU-974 umask test failed"
10362         if [ $MDSCOUNT -ge 2 ]; then
10363                 run_acl_subtest 974_remote ||
10364                         error "LU-974 umask test failed under remote dir"
10365         fi
10366
10367         echo "LU-2561 newly created file is same size as directory..."
10368         if [ "$mds1_FSTYPE" != "zfs" ]; then
10369                 run_acl_subtest 2561 || error "LU-2561 test failed"
10370         else
10371                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10372         fi
10373
10374         run_acl_subtest 4924 || error "LU-4924 test failed"
10375
10376         cd $SAVE_PWD
10377         umask $SAVE_UMASK
10378
10379         for num in $(seq $MDSCOUNT); do
10380                 if [ "${identity_old[$num]}" = 1 ]; then
10381                         switch_identity $num false || identity_old[$num]=$?
10382                 fi
10383         done
10384 }
10385 run_test 103a "acl test"
10386
10387 test_103b() {
10388         declare -a pids
10389         local U
10390
10391         for U in {0..511}; do
10392                 {
10393                 local O=$(printf "%04o" $U)
10394
10395                 umask $(printf "%04o" $((511 ^ $O)))
10396                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10397                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10398
10399                 (( $S == ($O & 0666) )) ||
10400                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10401
10402                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10403                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10404                 (( $S == ($O & 0666) )) ||
10405                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10406
10407                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10408                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10409                 (( $S == ($O & 0666) )) ||
10410                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10411                 rm -f $DIR/$tfile.[smp]$0
10412                 } &
10413                 local pid=$!
10414
10415                 # limit the concurrently running threads to 64. LU-11878
10416                 local idx=$((U % 64))
10417                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10418                 pids[idx]=$pid
10419         done
10420         wait
10421 }
10422 run_test 103b "umask lfs setstripe"
10423
10424 test_103c() {
10425         mkdir -p $DIR/$tdir
10426         cp -rp $DIR/$tdir $DIR/$tdir.bak
10427
10428         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10429                 error "$DIR/$tdir shouldn't contain default ACL"
10430         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10431                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10432         true
10433 }
10434 run_test 103c "'cp -rp' won't set empty acl"
10435
10436 test_104a() {
10437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10438
10439         touch $DIR/$tfile
10440         lfs df || error "lfs df failed"
10441         lfs df -ih || error "lfs df -ih failed"
10442         lfs df -h $DIR || error "lfs df -h $DIR failed"
10443         lfs df -i $DIR || error "lfs df -i $DIR failed"
10444         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10445         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10446
10447         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10448         lctl --device %$OSC deactivate
10449         lfs df || error "lfs df with deactivated OSC failed"
10450         lctl --device %$OSC activate
10451         # wait the osc back to normal
10452         wait_osc_import_ready client ost
10453
10454         lfs df || error "lfs df with reactivated OSC failed"
10455         rm -f $DIR/$tfile
10456 }
10457 run_test 104a "lfs df [-ih] [path] test ========================="
10458
10459 test_104b() {
10460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10461         [ $RUNAS_ID -eq $UID ] &&
10462                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10463
10464         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10465                         grep "Permission denied" | wc -l)))
10466         if [ $denied_cnt -ne 0 ]; then
10467                 error "lfs check servers test failed"
10468         fi
10469 }
10470 run_test 104b "$RUNAS lfs check servers test ===================="
10471
10472 test_105a() {
10473         # doesn't work on 2.4 kernels
10474         touch $DIR/$tfile
10475         if $(flock_is_enabled); then
10476                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10477         else
10478                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10479         fi
10480         rm -f $DIR/$tfile
10481 }
10482 run_test 105a "flock when mounted without -o flock test ========"
10483
10484 test_105b() {
10485         touch $DIR/$tfile
10486         if $(flock_is_enabled); then
10487                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10488         else
10489                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10490         fi
10491         rm -f $DIR/$tfile
10492 }
10493 run_test 105b "fcntl when mounted without -o flock test ========"
10494
10495 test_105c() {
10496         touch $DIR/$tfile
10497         if $(flock_is_enabled); then
10498                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10499         else
10500                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10501         fi
10502         rm -f $DIR/$tfile
10503 }
10504 run_test 105c "lockf when mounted without -o flock test"
10505
10506 test_105d() { # bug 15924
10507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10508
10509         test_mkdir $DIR/$tdir
10510         flock_is_enabled || skip_env "mount w/o flock enabled"
10511         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10512         $LCTL set_param fail_loc=0x80000315
10513         flocks_test 2 $DIR/$tdir
10514 }
10515 run_test 105d "flock race (should not freeze) ========"
10516
10517 test_105e() { # bug 22660 && 22040
10518         flock_is_enabled || skip_env "mount w/o flock enabled"
10519
10520         touch $DIR/$tfile
10521         flocks_test 3 $DIR/$tfile
10522 }
10523 run_test 105e "Two conflicting flocks from same process"
10524
10525 test_106() { #bug 10921
10526         test_mkdir $DIR/$tdir
10527         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10528         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10529 }
10530 run_test 106 "attempt exec of dir followed by chown of that dir"
10531
10532 test_107() {
10533         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10534
10535         CDIR=`pwd`
10536         local file=core
10537
10538         cd $DIR
10539         rm -f $file
10540
10541         local save_pattern=$(sysctl -n kernel.core_pattern)
10542         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10543         sysctl -w kernel.core_pattern=$file
10544         sysctl -w kernel.core_uses_pid=0
10545
10546         ulimit -c unlimited
10547         sleep 60 &
10548         SLEEPPID=$!
10549
10550         sleep 1
10551
10552         kill -s 11 $SLEEPPID
10553         wait $SLEEPPID
10554         if [ -e $file ]; then
10555                 size=`stat -c%s $file`
10556                 [ $size -eq 0 ] && error "Fail to create core file $file"
10557         else
10558                 error "Fail to create core file $file"
10559         fi
10560         rm -f $file
10561         sysctl -w kernel.core_pattern=$save_pattern
10562         sysctl -w kernel.core_uses_pid=$save_uses_pid
10563         cd $CDIR
10564 }
10565 run_test 107 "Coredump on SIG"
10566
10567 test_110() {
10568         test_mkdir $DIR/$tdir
10569         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10570         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10571                 error "mkdir with 256 char should fail, but did not"
10572         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10573                 error "create with 255 char failed"
10574         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10575                 error "create with 256 char should fail, but did not"
10576
10577         ls -l $DIR/$tdir
10578         rm -rf $DIR/$tdir
10579 }
10580 run_test 110 "filename length checking"
10581
10582 #
10583 # Purpose: To verify dynamic thread (OSS) creation.
10584 #
10585 test_115() {
10586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10587         remote_ost_nodsh && skip "remote OST with nodsh"
10588
10589         # Lustre does not stop service threads once they are started.
10590         # Reset number of running threads to default.
10591         stopall
10592         setupall
10593
10594         local OSTIO_pre
10595         local save_params="$TMP/sanity-$TESTNAME.parameters"
10596
10597         # Get ll_ost_io count before I/O
10598         OSTIO_pre=$(do_facet ost1 \
10599                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10600         # Exit if lustre is not running (ll_ost_io not running).
10601         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10602
10603         echo "Starting with $OSTIO_pre threads"
10604         local thread_max=$((OSTIO_pre * 2))
10605         local rpc_in_flight=$((thread_max * 2))
10606         # Number of I/O Process proposed to be started.
10607         local nfiles
10608         local facets=$(get_facets OST)
10609
10610         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10611         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10612
10613         # Set in_flight to $rpc_in_flight
10614         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10615                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10616         nfiles=${rpc_in_flight}
10617         # Set ost thread_max to $thread_max
10618         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10619
10620         # 5 Minutes should be sufficient for max number of OSS
10621         # threads(thread_max) to be created.
10622         local timeout=300
10623
10624         # Start I/O.
10625         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10626         test_mkdir $DIR/$tdir
10627         for i in $(seq $nfiles); do
10628                 local file=$DIR/$tdir/${tfile}-$i
10629                 $LFS setstripe -c -1 -i 0 $file
10630                 ($WTL $file $timeout)&
10631         done
10632
10633         # I/O Started - Wait for thread_started to reach thread_max or report
10634         # error if thread_started is more than thread_max.
10635         echo "Waiting for thread_started to reach thread_max"
10636         local thread_started=0
10637         local end_time=$((SECONDS + timeout))
10638
10639         while [ $SECONDS -le $end_time ] ; do
10640                 echo -n "."
10641                 # Get ost i/o thread_started count.
10642                 thread_started=$(do_facet ost1 \
10643                         "$LCTL get_param \
10644                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10645                 # Break out if thread_started is equal/greater than thread_max
10646                 if [[ $thread_started -ge $thread_max ]]; then
10647                         echo ll_ost_io thread_started $thread_started, \
10648                                 equal/greater than thread_max $thread_max
10649                         break
10650                 fi
10651                 sleep 1
10652         done
10653
10654         # Cleanup - We have the numbers, Kill i/o jobs if running.
10655         jobcount=($(jobs -p))
10656         for i in $(seq 0 $((${#jobcount[@]}-1)))
10657         do
10658                 kill -9 ${jobcount[$i]}
10659                 if [ $? -ne 0 ] ; then
10660                         echo Warning: \
10661                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10662                 fi
10663         done
10664
10665         # Cleanup files left by WTL binary.
10666         for i in $(seq $nfiles); do
10667                 local file=$DIR/$tdir/${tfile}-$i
10668                 rm -rf $file
10669                 if [ $? -ne 0 ] ; then
10670                         echo "Warning: Failed to delete file $file"
10671                 fi
10672         done
10673
10674         restore_lustre_params <$save_params
10675         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10676
10677         # Error out if no new thread has started or Thread started is greater
10678         # than thread max.
10679         if [[ $thread_started -le $OSTIO_pre ||
10680                         $thread_started -gt $thread_max ]]; then
10681                 error "ll_ost_io: thread_started $thread_started" \
10682                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10683                       "No new thread started or thread started greater " \
10684                       "than thread_max."
10685         fi
10686 }
10687 run_test 115 "verify dynamic thread creation===================="
10688
10689 free_min_max () {
10690         wait_delete_completed
10691         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10692         echo "OST kbytes available: ${AVAIL[@]}"
10693         MAXV=${AVAIL[0]}
10694         MAXI=0
10695         MINV=${AVAIL[0]}
10696         MINI=0
10697         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10698                 #echo OST $i: ${AVAIL[i]}kb
10699                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10700                         MAXV=${AVAIL[i]}
10701                         MAXI=$i
10702                 fi
10703                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10704                         MINV=${AVAIL[i]}
10705                         MINI=$i
10706                 fi
10707         done
10708         echo "Min free space: OST $MINI: $MINV"
10709         echo "Max free space: OST $MAXI: $MAXV"
10710 }
10711
10712 test_116a() { # was previously test_116()
10713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10714         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10715         remote_mds_nodsh && skip "remote MDS with nodsh"
10716
10717         echo -n "Free space priority "
10718         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10719                 head -n1
10720         declare -a AVAIL
10721         free_min_max
10722
10723         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10724         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10725         trap simple_cleanup_common EXIT
10726
10727         # Check if we need to generate uneven OSTs
10728         test_mkdir -p $DIR/$tdir/OST${MINI}
10729         local FILL=$((MINV / 4))
10730         local DIFF=$((MAXV - MINV))
10731         local DIFF2=$((DIFF * 100 / MINV))
10732
10733         local threshold=$(do_facet $SINGLEMDS \
10734                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10735         threshold=${threshold%%%}
10736         echo -n "Check for uneven OSTs: "
10737         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10738
10739         if [[ $DIFF2 -gt $threshold ]]; then
10740                 echo "ok"
10741                 echo "Don't need to fill OST$MINI"
10742         else
10743                 # generate uneven OSTs. Write 2% over the QOS threshold value
10744                 echo "no"
10745                 DIFF=$((threshold - DIFF2 + 2))
10746                 DIFF2=$((MINV * DIFF / 100))
10747                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10748                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10749                         error "setstripe failed"
10750                 DIFF=$((DIFF2 / 2048))
10751                 i=0
10752                 while [ $i -lt $DIFF ]; do
10753                         i=$((i + 1))
10754                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10755                                 bs=2M count=1 2>/dev/null
10756                         echo -n .
10757                 done
10758                 echo .
10759                 sync
10760                 sleep_maxage
10761                 free_min_max
10762         fi
10763
10764         DIFF=$((MAXV - MINV))
10765         DIFF2=$((DIFF * 100 / MINV))
10766         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10767         if [ $DIFF2 -gt $threshold ]; then
10768                 echo "ok"
10769         else
10770                 echo "failed - QOS mode won't be used"
10771                 simple_cleanup_common
10772                 skip "QOS imbalance criteria not met"
10773         fi
10774
10775         MINI1=$MINI
10776         MINV1=$MINV
10777         MAXI1=$MAXI
10778         MAXV1=$MAXV
10779
10780         # now fill using QOS
10781         $LFS setstripe -c 1 $DIR/$tdir
10782         FILL=$((FILL / 200))
10783         if [ $FILL -gt 600 ]; then
10784                 FILL=600
10785         fi
10786         echo "writing $FILL files to QOS-assigned OSTs"
10787         i=0
10788         while [ $i -lt $FILL ]; do
10789                 i=$((i + 1))
10790                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10791                         count=1 2>/dev/null
10792                 echo -n .
10793         done
10794         echo "wrote $i 200k files"
10795         sync
10796         sleep_maxage
10797
10798         echo "Note: free space may not be updated, so measurements might be off"
10799         free_min_max
10800         DIFF2=$((MAXV - MINV))
10801         echo "free space delta: orig $DIFF final $DIFF2"
10802         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10803         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10804         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10805         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10806         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10807         if [[ $DIFF -gt 0 ]]; then
10808                 FILL=$((DIFF2 * 100 / DIFF - 100))
10809                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10810         fi
10811
10812         # Figure out which files were written where
10813         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10814                awk '/'$MINI1': / {print $2; exit}')
10815         echo $UUID
10816         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10817         echo "$MINC files created on smaller OST $MINI1"
10818         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10819                awk '/'$MAXI1': / {print $2; exit}')
10820         echo $UUID
10821         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10822         echo "$MAXC files created on larger OST $MAXI1"
10823         if [[ $MINC -gt 0 ]]; then
10824                 FILL=$((MAXC * 100 / MINC - 100))
10825                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10826         fi
10827         [[ $MAXC -gt $MINC ]] ||
10828                 error_ignore LU-9 "stripe QOS didn't balance free space"
10829         simple_cleanup_common
10830 }
10831 run_test 116a "stripe QOS: free space balance ==================="
10832
10833 test_116b() { # LU-2093
10834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10835         remote_mds_nodsh && skip "remote MDS with nodsh"
10836
10837 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10838         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10839                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10840         [ -z "$old_rr" ] && skip "no QOS"
10841         do_facet $SINGLEMDS lctl set_param \
10842                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10843         mkdir -p $DIR/$tdir
10844         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10845         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10846         do_facet $SINGLEMDS lctl set_param fail_loc=0
10847         rm -rf $DIR/$tdir
10848         do_facet $SINGLEMDS lctl set_param \
10849                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10850 }
10851 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10852
10853 test_117() # bug 10891
10854 {
10855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10856
10857         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10858         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10859         lctl set_param fail_loc=0x21e
10860         > $DIR/$tfile || error "truncate failed"
10861         lctl set_param fail_loc=0
10862         echo "Truncate succeeded."
10863         rm -f $DIR/$tfile
10864 }
10865 run_test 117 "verify osd extend =========="
10866
10867 NO_SLOW_RESENDCOUNT=4
10868 export OLD_RESENDCOUNT=""
10869 set_resend_count () {
10870         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10871         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10872         lctl set_param -n $PROC_RESENDCOUNT $1
10873         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10874 }
10875
10876 # for reduce test_118* time (b=14842)
10877 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10878
10879 # Reset async IO behavior after error case
10880 reset_async() {
10881         FILE=$DIR/reset_async
10882
10883         # Ensure all OSCs are cleared
10884         $LFS setstripe -c -1 $FILE
10885         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10886         sync
10887         rm $FILE
10888 }
10889
10890 test_118a() #bug 11710
10891 {
10892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10893
10894         reset_async
10895
10896         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10897         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10898         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10899
10900         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10901                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10902                 return 1;
10903         fi
10904         rm -f $DIR/$tfile
10905 }
10906 run_test 118a "verify O_SYNC works =========="
10907
10908 test_118b()
10909 {
10910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10911         remote_ost_nodsh && skip "remote OST with nodsh"
10912
10913         reset_async
10914
10915         #define OBD_FAIL_SRV_ENOENT 0x217
10916         set_nodes_failloc "$(osts_nodes)" 0x217
10917         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10918         RC=$?
10919         set_nodes_failloc "$(osts_nodes)" 0
10920         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10921         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10922                     grep -c writeback)
10923
10924         if [[ $RC -eq 0 ]]; then
10925                 error "Must return error due to dropped pages, rc=$RC"
10926                 return 1;
10927         fi
10928
10929         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10930                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10931                 return 1;
10932         fi
10933
10934         echo "Dirty pages not leaked on ENOENT"
10935
10936         # Due to the above error the OSC will issue all RPCs syncronously
10937         # until a subsequent RPC completes successfully without error.
10938         $MULTIOP $DIR/$tfile Ow4096yc
10939         rm -f $DIR/$tfile
10940
10941         return 0
10942 }
10943 run_test 118b "Reclaim dirty pages on fatal error =========="
10944
10945 test_118c()
10946 {
10947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10948
10949         # for 118c, restore the original resend count, LU-1940
10950         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10951                                 set_resend_count $OLD_RESENDCOUNT
10952         remote_ost_nodsh && skip "remote OST with nodsh"
10953
10954         reset_async
10955
10956         #define OBD_FAIL_OST_EROFS               0x216
10957         set_nodes_failloc "$(osts_nodes)" 0x216
10958
10959         # multiop should block due to fsync until pages are written
10960         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10961         MULTIPID=$!
10962         sleep 1
10963
10964         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10965                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10966         fi
10967
10968         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10969                     grep -c writeback)
10970         if [[ $WRITEBACK -eq 0 ]]; then
10971                 error "No page in writeback, writeback=$WRITEBACK"
10972         fi
10973
10974         set_nodes_failloc "$(osts_nodes)" 0
10975         wait $MULTIPID
10976         RC=$?
10977         if [[ $RC -ne 0 ]]; then
10978                 error "Multiop fsync failed, rc=$RC"
10979         fi
10980
10981         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10982         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10983                     grep -c writeback)
10984         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10985                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10986         fi
10987
10988         rm -f $DIR/$tfile
10989         echo "Dirty pages flushed via fsync on EROFS"
10990         return 0
10991 }
10992 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
10993
10994 # continue to use small resend count to reduce test_118* time (b=14842)
10995 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10996
10997 test_118d()
10998 {
10999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11000         remote_ost_nodsh && skip "remote OST with nodsh"
11001
11002         reset_async
11003
11004         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11005         set_nodes_failloc "$(osts_nodes)" 0x214
11006         # multiop should block due to fsync until pages are written
11007         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11008         MULTIPID=$!
11009         sleep 1
11010
11011         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11012                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11013         fi
11014
11015         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11016                     grep -c writeback)
11017         if [[ $WRITEBACK -eq 0 ]]; then
11018                 error "No page in writeback, writeback=$WRITEBACK"
11019         fi
11020
11021         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11022         set_nodes_failloc "$(osts_nodes)" 0
11023
11024         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11025         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11026                     grep -c writeback)
11027         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11028                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11029         fi
11030
11031         rm -f $DIR/$tfile
11032         echo "Dirty pages gaurenteed flushed via fsync"
11033         return 0
11034 }
11035 run_test 118d "Fsync validation inject a delay of the bulk =========="
11036
11037 test_118f() {
11038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11039
11040         reset_async
11041
11042         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11043         lctl set_param fail_loc=0x8000040a
11044
11045         # Should simulate EINVAL error which is fatal
11046         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11047         RC=$?
11048         if [[ $RC -eq 0 ]]; then
11049                 error "Must return error due to dropped pages, rc=$RC"
11050         fi
11051
11052         lctl set_param fail_loc=0x0
11053
11054         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11055         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11056         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11057                     grep -c writeback)
11058         if [[ $LOCKED -ne 0 ]]; then
11059                 error "Locked pages remain in cache, locked=$LOCKED"
11060         fi
11061
11062         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11063                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11064         fi
11065
11066         rm -f $DIR/$tfile
11067         echo "No pages locked after fsync"
11068
11069         reset_async
11070         return 0
11071 }
11072 run_test 118f "Simulate unrecoverable OSC side error =========="
11073
11074 test_118g() {
11075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11076
11077         reset_async
11078
11079         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11080         lctl set_param fail_loc=0x406
11081
11082         # simulate local -ENOMEM
11083         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11084         RC=$?
11085
11086         lctl set_param fail_loc=0
11087         if [[ $RC -eq 0 ]]; then
11088                 error "Must return error due to dropped pages, rc=$RC"
11089         fi
11090
11091         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11092         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11093         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11094                         grep -c writeback)
11095         if [[ $LOCKED -ne 0 ]]; then
11096                 error "Locked pages remain in cache, locked=$LOCKED"
11097         fi
11098
11099         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11100                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11101         fi
11102
11103         rm -f $DIR/$tfile
11104         echo "No pages locked after fsync"
11105
11106         reset_async
11107         return 0
11108 }
11109 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11110
11111 test_118h() {
11112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11113         remote_ost_nodsh && skip "remote OST with nodsh"
11114
11115         reset_async
11116
11117         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11118         set_nodes_failloc "$(osts_nodes)" 0x20e
11119         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11120         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11121         RC=$?
11122
11123         set_nodes_failloc "$(osts_nodes)" 0
11124         if [[ $RC -eq 0 ]]; then
11125                 error "Must return error due to dropped pages, rc=$RC"
11126         fi
11127
11128         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11129         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11130         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11131                     grep -c writeback)
11132         if [[ $LOCKED -ne 0 ]]; then
11133                 error "Locked pages remain in cache, locked=$LOCKED"
11134         fi
11135
11136         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11137                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11138         fi
11139
11140         rm -f $DIR/$tfile
11141         echo "No pages locked after fsync"
11142
11143         return 0
11144 }
11145 run_test 118h "Verify timeout in handling recoverables errors  =========="
11146
11147 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11148
11149 test_118i() {
11150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11151         remote_ost_nodsh && skip "remote OST with nodsh"
11152
11153         reset_async
11154
11155         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11156         set_nodes_failloc "$(osts_nodes)" 0x20e
11157
11158         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11159         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11160         PID=$!
11161         sleep 5
11162         set_nodes_failloc "$(osts_nodes)" 0
11163
11164         wait $PID
11165         RC=$?
11166         if [[ $RC -ne 0 ]]; then
11167                 error "got error, but should be not, rc=$RC"
11168         fi
11169
11170         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11171         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11172         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11173         if [[ $LOCKED -ne 0 ]]; then
11174                 error "Locked pages remain in cache, locked=$LOCKED"
11175         fi
11176
11177         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11178                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11179         fi
11180
11181         rm -f $DIR/$tfile
11182         echo "No pages locked after fsync"
11183
11184         return 0
11185 }
11186 run_test 118i "Fix error before timeout in recoverable error  =========="
11187
11188 [ "$SLOW" = "no" ] && set_resend_count 4
11189
11190 test_118j() {
11191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11192         remote_ost_nodsh && skip "remote OST with nodsh"
11193
11194         reset_async
11195
11196         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11197         set_nodes_failloc "$(osts_nodes)" 0x220
11198
11199         # return -EIO from OST
11200         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11201         RC=$?
11202         set_nodes_failloc "$(osts_nodes)" 0x0
11203         if [[ $RC -eq 0 ]]; then
11204                 error "Must return error due to dropped pages, rc=$RC"
11205         fi
11206
11207         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11208         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11209         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11210         if [[ $LOCKED -ne 0 ]]; then
11211                 error "Locked pages remain in cache, locked=$LOCKED"
11212         fi
11213
11214         # in recoverable error on OST we want resend and stay until it finished
11215         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11216                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11217         fi
11218
11219         rm -f $DIR/$tfile
11220         echo "No pages locked after fsync"
11221
11222         return 0
11223 }
11224 run_test 118j "Simulate unrecoverable OST side error =========="
11225
11226 test_118k()
11227 {
11228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11229         remote_ost_nodsh && skip "remote OSTs with nodsh"
11230
11231         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11232         set_nodes_failloc "$(osts_nodes)" 0x20e
11233         test_mkdir $DIR/$tdir
11234
11235         for ((i=0;i<10;i++)); do
11236                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11237                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11238                 SLEEPPID=$!
11239                 sleep 0.500s
11240                 kill $SLEEPPID
11241                 wait $SLEEPPID
11242         done
11243
11244         set_nodes_failloc "$(osts_nodes)" 0
11245         rm -rf $DIR/$tdir
11246 }
11247 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11248
11249 test_118l() # LU-646
11250 {
11251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11252
11253         test_mkdir $DIR/$tdir
11254         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11255         rm -rf $DIR/$tdir
11256 }
11257 run_test 118l "fsync dir"
11258
11259 test_118m() # LU-3066
11260 {
11261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11262
11263         test_mkdir $DIR/$tdir
11264         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11265         rm -rf $DIR/$tdir
11266 }
11267 run_test 118m "fdatasync dir ========="
11268
11269 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11270
11271 test_118n()
11272 {
11273         local begin
11274         local end
11275
11276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11277         remote_ost_nodsh && skip "remote OSTs with nodsh"
11278
11279         # Sleep to avoid a cached response.
11280         #define OBD_STATFS_CACHE_SECONDS 1
11281         sleep 2
11282
11283         # Inject a 10 second delay in the OST_STATFS handler.
11284         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11285         set_nodes_failloc "$(osts_nodes)" 0x242
11286
11287         begin=$SECONDS
11288         stat --file-system $MOUNT > /dev/null
11289         end=$SECONDS
11290
11291         set_nodes_failloc "$(osts_nodes)" 0
11292
11293         if ((end - begin > 20)); then
11294             error "statfs took $((end - begin)) seconds, expected 10"
11295         fi
11296 }
11297 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11298
11299 test_119a() # bug 11737
11300 {
11301         BSIZE=$((512 * 1024))
11302         directio write $DIR/$tfile 0 1 $BSIZE
11303         # We ask to read two blocks, which is more than a file size.
11304         # directio will indicate an error when requested and actual
11305         # sizes aren't equeal (a normal situation in this case) and
11306         # print actual read amount.
11307         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11308         if [ "$NOB" != "$BSIZE" ]; then
11309                 error "read $NOB bytes instead of $BSIZE"
11310         fi
11311         rm -f $DIR/$tfile
11312 }
11313 run_test 119a "Short directIO read must return actual read amount"
11314
11315 test_119b() # bug 11737
11316 {
11317         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11318
11319         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11320         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11321         sync
11322         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11323                 error "direct read failed"
11324         rm -f $DIR/$tfile
11325 }
11326 run_test 119b "Sparse directIO read must return actual read amount"
11327
11328 test_119c() # bug 13099
11329 {
11330         BSIZE=1048576
11331         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11332         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11333         rm -f $DIR/$tfile
11334 }
11335 run_test 119c "Testing for direct read hitting hole"
11336
11337 test_119d() # bug 15950
11338 {
11339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11340
11341         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11342         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11343         BSIZE=1048576
11344         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11345         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11346         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11347         lctl set_param fail_loc=0x40d
11348         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11349         pid_dio=$!
11350         sleep 1
11351         cat $DIR/$tfile > /dev/null &
11352         lctl set_param fail_loc=0
11353         pid_reads=$!
11354         wait $pid_dio
11355         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11356         sleep 2
11357         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11358         error "the read rpcs have not completed in 2s"
11359         rm -f $DIR/$tfile
11360         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11361 }
11362 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11363
11364 test_120a() {
11365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11366         remote_mds_nodsh && skip "remote MDS with nodsh"
11367         test_mkdir -i0 -c1 $DIR/$tdir
11368         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11369                 skip_env "no early lock cancel on server"
11370
11371         lru_resize_disable mdc
11372         lru_resize_disable osc
11373         cancel_lru_locks mdc
11374         # asynchronous object destroy at MDT could cause bl ast to client
11375         cancel_lru_locks osc
11376
11377         stat $DIR/$tdir > /dev/null
11378         can1=$(do_facet mds1 \
11379                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11380                awk '/ldlm_cancel/ {print $2}')
11381         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11382                awk '/ldlm_bl_callback/ {print $2}')
11383         test_mkdir -i0 -c1 $DIR/$tdir/d1
11384         can2=$(do_facet mds1 \
11385                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11386                awk '/ldlm_cancel/ {print $2}')
11387         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11388                awk '/ldlm_bl_callback/ {print $2}')
11389         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11390         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11391         lru_resize_enable mdc
11392         lru_resize_enable osc
11393 }
11394 run_test 120a "Early Lock Cancel: mkdir test"
11395
11396 test_120b() {
11397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11398         remote_mds_nodsh && skip "remote MDS with nodsh"
11399         test_mkdir $DIR/$tdir
11400         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11401                 skip_env "no early lock cancel on server"
11402
11403         lru_resize_disable mdc
11404         lru_resize_disable osc
11405         cancel_lru_locks mdc
11406         stat $DIR/$tdir > /dev/null
11407         can1=$(do_facet $SINGLEMDS \
11408                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11409                awk '/ldlm_cancel/ {print $2}')
11410         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11411                awk '/ldlm_bl_callback/ {print $2}')
11412         touch $DIR/$tdir/f1
11413         can2=$(do_facet $SINGLEMDS \
11414                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11415                awk '/ldlm_cancel/ {print $2}')
11416         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11417                awk '/ldlm_bl_callback/ {print $2}')
11418         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11419         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11420         lru_resize_enable mdc
11421         lru_resize_enable osc
11422 }
11423 run_test 120b "Early Lock Cancel: create test"
11424
11425 test_120c() {
11426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11427         remote_mds_nodsh && skip "remote MDS with nodsh"
11428         test_mkdir -i0 -c1 $DIR/$tdir
11429         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11430                 skip "no early lock cancel on server"
11431
11432         lru_resize_disable mdc
11433         lru_resize_disable osc
11434         test_mkdir -i0 -c1 $DIR/$tdir/d1
11435         test_mkdir -i0 -c1 $DIR/$tdir/d2
11436         touch $DIR/$tdir/d1/f1
11437         cancel_lru_locks mdc
11438         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11439         can1=$(do_facet mds1 \
11440                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11441                awk '/ldlm_cancel/ {print $2}')
11442         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11443                awk '/ldlm_bl_callback/ {print $2}')
11444         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11445         can2=$(do_facet mds1 \
11446                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11447                awk '/ldlm_cancel/ {print $2}')
11448         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11449                awk '/ldlm_bl_callback/ {print $2}')
11450         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11451         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11452         lru_resize_enable mdc
11453         lru_resize_enable osc
11454 }
11455 run_test 120c "Early Lock Cancel: link test"
11456
11457 test_120d() {
11458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11459         remote_mds_nodsh && skip "remote MDS with nodsh"
11460         test_mkdir -i0 -c1 $DIR/$tdir
11461         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11462                 skip_env "no early lock cancel on server"
11463
11464         lru_resize_disable mdc
11465         lru_resize_disable osc
11466         touch $DIR/$tdir
11467         cancel_lru_locks mdc
11468         stat $DIR/$tdir > /dev/null
11469         can1=$(do_facet mds1 \
11470                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11471                awk '/ldlm_cancel/ {print $2}')
11472         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11473                awk '/ldlm_bl_callback/ {print $2}')
11474         chmod a+x $DIR/$tdir
11475         can2=$(do_facet mds1 \
11476                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11477                awk '/ldlm_cancel/ {print $2}')
11478         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11479                awk '/ldlm_bl_callback/ {print $2}')
11480         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11481         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11482         lru_resize_enable mdc
11483         lru_resize_enable osc
11484 }
11485 run_test 120d "Early Lock Cancel: setattr test"
11486
11487 test_120e() {
11488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11489         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11490                 skip_env "no early lock cancel on server"
11491         remote_mds_nodsh && skip "remote MDS with nodsh"
11492
11493         local dlmtrace_set=false
11494
11495         test_mkdir -i0 -c1 $DIR/$tdir
11496         lru_resize_disable mdc
11497         lru_resize_disable osc
11498         ! $LCTL get_param debug | grep -q dlmtrace &&
11499                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11500         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11501         cancel_lru_locks mdc
11502         cancel_lru_locks osc
11503         dd if=$DIR/$tdir/f1 of=/dev/null
11504         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11505         # XXX client can not do early lock cancel of OST lock
11506         # during unlink (LU-4206), so cancel osc lock now.
11507         sleep 2
11508         cancel_lru_locks osc
11509         can1=$(do_facet mds1 \
11510                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11511                awk '/ldlm_cancel/ {print $2}')
11512         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11513                awk '/ldlm_bl_callback/ {print $2}')
11514         unlink $DIR/$tdir/f1
11515         sleep 5
11516         can2=$(do_facet mds1 \
11517                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11518                awk '/ldlm_cancel/ {print $2}')
11519         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11520                awk '/ldlm_bl_callback/ {print $2}')
11521         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11522                 $LCTL dk $TMP/cancel.debug.txt
11523         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11524                 $LCTL dk $TMP/blocking.debug.txt
11525         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11526         lru_resize_enable mdc
11527         lru_resize_enable osc
11528 }
11529 run_test 120e "Early Lock Cancel: unlink test"
11530
11531 test_120f() {
11532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11533         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11534                 skip_env "no early lock cancel on server"
11535         remote_mds_nodsh && skip "remote MDS with nodsh"
11536
11537         test_mkdir -i0 -c1 $DIR/$tdir
11538         lru_resize_disable mdc
11539         lru_resize_disable osc
11540         test_mkdir -i0 -c1 $DIR/$tdir/d1
11541         test_mkdir -i0 -c1 $DIR/$tdir/d2
11542         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11543         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11544         cancel_lru_locks mdc
11545         cancel_lru_locks osc
11546         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11547         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11548         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11549         # XXX client can not do early lock cancel of OST lock
11550         # during rename (LU-4206), so cancel osc lock now.
11551         sleep 2
11552         cancel_lru_locks osc
11553         can1=$(do_facet mds1 \
11554                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11555                awk '/ldlm_cancel/ {print $2}')
11556         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11557                awk '/ldlm_bl_callback/ {print $2}')
11558         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11559         sleep 5
11560         can2=$(do_facet mds1 \
11561                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11562                awk '/ldlm_cancel/ {print $2}')
11563         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11564                awk '/ldlm_bl_callback/ {print $2}')
11565         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11566         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11567         lru_resize_enable mdc
11568         lru_resize_enable osc
11569 }
11570 run_test 120f "Early Lock Cancel: rename test"
11571
11572 test_120g() {
11573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11574         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11575                 skip_env "no early lock cancel on server"
11576         remote_mds_nodsh && skip "remote MDS with nodsh"
11577
11578         lru_resize_disable mdc
11579         lru_resize_disable osc
11580         count=10000
11581         echo create $count files
11582         test_mkdir $DIR/$tdir
11583         cancel_lru_locks mdc
11584         cancel_lru_locks osc
11585         t0=$(date +%s)
11586
11587         can0=$(do_facet $SINGLEMDS \
11588                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11589                awk '/ldlm_cancel/ {print $2}')
11590         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11591                awk '/ldlm_bl_callback/ {print $2}')
11592         createmany -o $DIR/$tdir/f $count
11593         sync
11594         can1=$(do_facet $SINGLEMDS \
11595                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11596                awk '/ldlm_cancel/ {print $2}')
11597         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11598                awk '/ldlm_bl_callback/ {print $2}')
11599         t1=$(date +%s)
11600         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11601         echo rm $count files
11602         rm -r $DIR/$tdir
11603         sync
11604         can2=$(do_facet $SINGLEMDS \
11605                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11606                awk '/ldlm_cancel/ {print $2}')
11607         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11608                awk '/ldlm_bl_callback/ {print $2}')
11609         t2=$(date +%s)
11610         echo total: $count removes in $((t2-t1))
11611         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11612         sleep 2
11613         # wait for commitment of removal
11614         lru_resize_enable mdc
11615         lru_resize_enable osc
11616 }
11617 run_test 120g "Early Lock Cancel: performance test"
11618
11619 test_121() { #bug #10589
11620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11621
11622         rm -rf $DIR/$tfile
11623         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11624 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11625         lctl set_param fail_loc=0x310
11626         cancel_lru_locks osc > /dev/null
11627         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11628         lctl set_param fail_loc=0
11629         [[ $reads -eq $writes ]] ||
11630                 error "read $reads blocks, must be $writes blocks"
11631 }
11632 run_test 121 "read cancel race ========="
11633
11634 test_123a_base() { # was test 123, statahead(bug 11401)
11635         local lsx="$1"
11636
11637         SLOWOK=0
11638         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11639                 log "testing UP system. Performance may be lower than expected."
11640                 SLOWOK=1
11641         fi
11642
11643         rm -rf $DIR/$tdir
11644         test_mkdir $DIR/$tdir
11645         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11646         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11647         MULT=10
11648         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11649                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11650
11651                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
11652                 lctl set_param -n llite.*.statahead_max 0
11653                 lctl get_param llite.*.statahead_max
11654                 cancel_lru_locks mdc
11655                 cancel_lru_locks osc
11656                 stime=$(date +%s)
11657                 time $lsx $DIR/$tdir | wc -l
11658                 etime=$(date +%s)
11659                 delta=$((etime - stime))
11660                 log "$lsx $i files without statahead: $delta sec"
11661                 lctl set_param llite.*.statahead_max=$max
11662
11663                 swrong=$(lctl get_param -n llite.*.statahead_stats |
11664                         grep "statahead wrong:" | awk '{print $3}')
11665                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11666                 cancel_lru_locks mdc
11667                 cancel_lru_locks osc
11668                 stime=$(date +%s)
11669                 time $lsx $DIR/$tdir | wc -l
11670                 etime=$(date +%s)
11671                 delta_sa=$((etime - stime))
11672                 log "$lsx $i files with statahead: $delta_sa sec"
11673                 lctl get_param -n llite.*.statahead_stats
11674                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
11675                         grep "statahead wrong:" | awk '{print $3}')
11676
11677                 [[ $swrong -lt $ewrong ]] &&
11678                         log "statahead was stopped, maybe too many locks held!"
11679                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11680
11681                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11682                         max=$(lctl get_param -n llite.*.statahead_max |
11683                                 head -n 1)
11684                         lctl set_param -n llite.*.statahead_max 0
11685                         lctl get_param llite.*.statahead_max
11686                         cancel_lru_locks mdc
11687                         cancel_lru_locks osc
11688                         stime=$(date +%s)
11689                         time $lsx $DIR/$tdir | wc -l
11690                         etime=$(date +%s)
11691                         delta=$((etime - stime))
11692                         log "$lsx $i files again without statahead: $delta sec"
11693                         lctl set_param llite.*.statahead_max=$max
11694                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
11695                                 if [  $SLOWOK -eq 0 ]; then
11696                                         error "$lsx $i files is slower with statahead!"
11697                                 else
11698                                         log "$lsx $i files is slower with statahead!"
11699                                 fi
11700                                 break
11701                         fi
11702                 fi
11703
11704                 [ $delta -gt 20 ] && break
11705                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11706                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11707         done
11708         log "$lsx done"
11709
11710         stime=$(date +%s)
11711         rm -r $DIR/$tdir
11712         sync
11713         etime=$(date +%s)
11714         delta=$((etime - stime))
11715         log "rm -r $DIR/$tdir/: $delta seconds"
11716         log "rm done"
11717         lctl get_param -n llite.*.statahead_stats
11718 }
11719
11720 test_123aa() {
11721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11722
11723         test_123a_base "ls -l"
11724 }
11725 run_test 123aa "verify statahead work"
11726
11727 test_123ab() {
11728         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11729
11730         statx_supported || skip_env "Test must be statx() syscall supported"
11731
11732         test_123a_base "$STATX -l"
11733 }
11734 run_test 123ab "verify statahead work by using statx"
11735
11736 test_123ac() {
11737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11738
11739         statx_supported || skip_env "Test must be statx() syscall supported"
11740
11741         local rpcs_before
11742         local rpcs_after
11743         local agl_before
11744         local agl_after
11745
11746         cancel_lru_locks $OSC
11747         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11748         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
11749                 awk '/agl.total:/ {print $3}')
11750         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
11751         test_123a_base "$STATX --cached=always -D"
11752         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
11753                 awk '/agl.total:/ {print $3}')
11754         [ $agl_before -eq $agl_after ] ||
11755                 error "Should not trigger AGL thread - $agl_before:$agl_after"
11756         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11757         [ $rpcs_after -eq $rpcs_before ] ||
11758                 error "$STATX should not send glimpse RPCs to $OSC"
11759 }
11760 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
11761
11762 test_123b () { # statahead(bug 15027)
11763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11764
11765         test_mkdir $DIR/$tdir
11766         createmany -o $DIR/$tdir/$tfile-%d 1000
11767
11768         cancel_lru_locks mdc
11769         cancel_lru_locks osc
11770
11771 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11772         lctl set_param fail_loc=0x80000803
11773         ls -lR $DIR/$tdir > /dev/null
11774         log "ls done"
11775         lctl set_param fail_loc=0x0
11776         lctl get_param -n llite.*.statahead_stats
11777         rm -r $DIR/$tdir
11778         sync
11779
11780 }
11781 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11782
11783 test_123c() {
11784         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11785
11786         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11787         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11788         touch $DIR/$tdir.1/{1..3}
11789         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11790
11791         remount_client $MOUNT
11792
11793         $MULTIOP $DIR/$tdir.0 Q
11794
11795         # let statahead to complete
11796         ls -l $DIR/$tdir.0 > /dev/null
11797
11798         testid=$(echo $TESTNAME | tr '_' ' ')
11799         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11800                 error "statahead warning" || true
11801 }
11802 run_test 123c "Can not initialize inode warning on DNE statahead"
11803
11804 test_124a() {
11805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11806         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11807                 skip_env "no lru resize on server"
11808
11809         local NR=2000
11810
11811         test_mkdir $DIR/$tdir
11812
11813         log "create $NR files at $DIR/$tdir"
11814         createmany -o $DIR/$tdir/f $NR ||
11815                 error "failed to create $NR files in $DIR/$tdir"
11816
11817         cancel_lru_locks mdc
11818         ls -l $DIR/$tdir > /dev/null
11819
11820         local NSDIR=""
11821         local LRU_SIZE=0
11822         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11823                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11824                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11825                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11826                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11827                         log "NSDIR=$NSDIR"
11828                         log "NS=$(basename $NSDIR)"
11829                         break
11830                 fi
11831         done
11832
11833         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11834                 skip "Not enough cached locks created!"
11835         fi
11836         log "LRU=$LRU_SIZE"
11837
11838         local SLEEP=30
11839
11840         # We know that lru resize allows one client to hold $LIMIT locks
11841         # for 10h. After that locks begin to be killed by client.
11842         local MAX_HRS=10
11843         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11844         log "LIMIT=$LIMIT"
11845         if [ $LIMIT -lt $LRU_SIZE ]; then
11846                 skip "Limit is too small $LIMIT"
11847         fi
11848
11849         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11850         # killing locks. Some time was spent for creating locks. This means
11851         # that up to the moment of sleep finish we must have killed some of
11852         # them (10-100 locks). This depends on how fast ther were created.
11853         # Many of them were touched in almost the same moment and thus will
11854         # be killed in groups.
11855         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
11856
11857         # Use $LRU_SIZE_B here to take into account real number of locks
11858         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11859         local LRU_SIZE_B=$LRU_SIZE
11860         log "LVF=$LVF"
11861         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11862         log "OLD_LVF=$OLD_LVF"
11863         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11864
11865         # Let's make sure that we really have some margin. Client checks
11866         # cached locks every 10 sec.
11867         SLEEP=$((SLEEP+20))
11868         log "Sleep ${SLEEP} sec"
11869         local SEC=0
11870         while ((SEC<$SLEEP)); do
11871                 echo -n "..."
11872                 sleep 5
11873                 SEC=$((SEC+5))
11874                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11875                 echo -n "$LRU_SIZE"
11876         done
11877         echo ""
11878         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11879         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11880
11881         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11882                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11883                 unlinkmany $DIR/$tdir/f $NR
11884                 return
11885         }
11886
11887         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11888         log "unlink $NR files at $DIR/$tdir"
11889         unlinkmany $DIR/$tdir/f $NR
11890 }
11891 run_test 124a "lru resize ======================================="
11892
11893 get_max_pool_limit()
11894 {
11895         local limit=$($LCTL get_param \
11896                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11897         local max=0
11898         for l in $limit; do
11899                 if [[ $l -gt $max ]]; then
11900                         max=$l
11901                 fi
11902         done
11903         echo $max
11904 }
11905
11906 test_124b() {
11907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11908         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11909                 skip_env "no lru resize on server"
11910
11911         LIMIT=$(get_max_pool_limit)
11912
11913         NR=$(($(default_lru_size)*20))
11914         if [[ $NR -gt $LIMIT ]]; then
11915                 log "Limit lock number by $LIMIT locks"
11916                 NR=$LIMIT
11917         fi
11918
11919         IFree=$(mdsrate_inodes_available)
11920         if [ $IFree -lt $NR ]; then
11921                 log "Limit lock number by $IFree inodes"
11922                 NR=$IFree
11923         fi
11924
11925         lru_resize_disable mdc
11926         test_mkdir -p $DIR/$tdir/disable_lru_resize
11927
11928         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11929         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11930         cancel_lru_locks mdc
11931         stime=`date +%s`
11932         PID=""
11933         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11934         PID="$PID $!"
11935         sleep 2
11936         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11937         PID="$PID $!"
11938         sleep 2
11939         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11940         PID="$PID $!"
11941         wait $PID
11942         etime=`date +%s`
11943         nolruresize_delta=$((etime-stime))
11944         log "ls -la time: $nolruresize_delta seconds"
11945         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11946         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11947
11948         lru_resize_enable mdc
11949         test_mkdir -p $DIR/$tdir/enable_lru_resize
11950
11951         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11952         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11953         cancel_lru_locks mdc
11954         stime=`date +%s`
11955         PID=""
11956         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11957         PID="$PID $!"
11958         sleep 2
11959         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11960         PID="$PID $!"
11961         sleep 2
11962         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11963         PID="$PID $!"
11964         wait $PID
11965         etime=`date +%s`
11966         lruresize_delta=$((etime-stime))
11967         log "ls -la time: $lruresize_delta seconds"
11968         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11969
11970         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11971                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11972         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11973                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11974         else
11975                 log "lru resize performs the same with no lru resize"
11976         fi
11977         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
11978 }
11979 run_test 124b "lru resize (performance test) ======================="
11980
11981 test_124c() {
11982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11983         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11984                 skip_env "no lru resize on server"
11985
11986         # cache ununsed locks on client
11987         local nr=100
11988         cancel_lru_locks mdc
11989         test_mkdir $DIR/$tdir
11990         createmany -o $DIR/$tdir/f $nr ||
11991                 error "failed to create $nr files in $DIR/$tdir"
11992         ls -l $DIR/$tdir > /dev/null
11993
11994         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11995         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11996         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11997         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11998         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11999
12000         # set lru_max_age to 1 sec
12001         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12002         echo "sleep $((recalc_p * 2)) seconds..."
12003         sleep $((recalc_p * 2))
12004
12005         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12006         # restore lru_max_age
12007         $LCTL set_param -n $nsdir.lru_max_age $max_age
12008         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12009         unlinkmany $DIR/$tdir/f $nr
12010 }
12011 run_test 124c "LRUR cancel very aged locks"
12012
12013 test_124d() {
12014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12015         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12016                 skip_env "no lru resize on server"
12017
12018         # cache ununsed locks on client
12019         local nr=100
12020
12021         lru_resize_disable mdc
12022         stack_trap "lru_resize_enable mdc" EXIT
12023
12024         cancel_lru_locks mdc
12025
12026         # asynchronous object destroy at MDT could cause bl ast to client
12027         test_mkdir $DIR/$tdir
12028         createmany -o $DIR/$tdir/f $nr ||
12029                 error "failed to create $nr files in $DIR/$tdir"
12030         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12031
12032         ls -l $DIR/$tdir > /dev/null
12033
12034         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12035         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12036         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12037         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12038
12039         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12040
12041         # set lru_max_age to 1 sec
12042         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12043         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12044
12045         echo "sleep $((recalc_p * 2)) seconds..."
12046         sleep $((recalc_p * 2))
12047
12048         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12049
12050         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12051 }
12052 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12053
12054 test_125() { # 13358
12055         $LCTL get_param -n llite.*.client_type | grep -q local ||
12056                 skip "must run as local client"
12057         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12058                 skip_env "must have acl enabled"
12059         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12060
12061         test_mkdir $DIR/$tdir
12062         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12063         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12064         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12065 }
12066 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12067
12068 test_126() { # bug 12829/13455
12069         $GSS && skip_env "must run as gss disabled"
12070         $LCTL get_param -n llite.*.client_type | grep -q local ||
12071                 skip "must run as local client"
12072         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12073
12074         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12075         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12076         rm -f $DIR/$tfile
12077         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12078 }
12079 run_test 126 "check that the fsgid provided by the client is taken into account"
12080
12081 test_127a() { # bug 15521
12082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12083         local name count samp unit min max sum sumsq
12084
12085         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12086         echo "stats before reset"
12087         $LCTL get_param osc.*.stats
12088         $LCTL set_param osc.*.stats=0
12089         local fsize=$((2048 * 1024))
12090
12091         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12092         cancel_lru_locks osc
12093         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12094
12095         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12096         stack_trap "rm -f $TMP/$tfile.tmp"
12097         while read name count samp unit min max sum sumsq; do
12098                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12099                 [ ! $min ] && error "Missing min value for $name proc entry"
12100                 eval $name=$count || error "Wrong proc format"
12101
12102                 case $name in
12103                 read_bytes|write_bytes)
12104                         [[ "$unit" =~ "bytes" ]] ||
12105                                 error "unit is not 'bytes': $unit"
12106                         (( $min >= 4096 )) || error "min is too small: $min"
12107                         (( $min <= $fsize )) || error "min is too big: $min"
12108                         (( $max >= 4096 )) || error "max is too small: $max"
12109                         (( $max <= $fsize )) || error "max is too big: $max"
12110                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12111                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12112                                 error "sumsquare is too small: $sumsq"
12113                         (( $sumsq <= $fsize * $fsize )) ||
12114                                 error "sumsquare is too big: $sumsq"
12115                         ;;
12116                 ost_read|ost_write)
12117                         [[ "$unit" =~ "usec" ]] ||
12118                                 error "unit is not 'usec': $unit"
12119                         ;;
12120                 *)      ;;
12121                 esac
12122         done < $DIR/$tfile.tmp
12123
12124         #check that we actually got some stats
12125         [ "$read_bytes" ] || error "Missing read_bytes stats"
12126         [ "$write_bytes" ] || error "Missing write_bytes stats"
12127         [ "$read_bytes" != 0 ] || error "no read done"
12128         [ "$write_bytes" != 0 ] || error "no write done"
12129 }
12130 run_test 127a "verify the client stats are sane"
12131
12132 test_127b() { # bug LU-333
12133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12134         local name count samp unit min max sum sumsq
12135
12136         echo "stats before reset"
12137         $LCTL get_param llite.*.stats
12138         $LCTL set_param llite.*.stats=0
12139
12140         # perform 2 reads and writes so MAX is different from SUM.
12141         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12142         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12143         cancel_lru_locks osc
12144         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12145         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12146
12147         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12148         stack_trap "rm -f $TMP/$tfile.tmp"
12149         while read name count samp unit min max sum sumsq; do
12150                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12151                 eval $name=$count || error "Wrong proc format"
12152
12153                 case $name in
12154                 read_bytes|write_bytes)
12155                         [[ "$unit" =~ "bytes" ]] ||
12156                                 error "unit is not 'bytes': $unit"
12157                         (( $count == 2 )) || error "count is not 2: $count"
12158                         (( $min == $PAGE_SIZE )) ||
12159                                 error "min is not $PAGE_SIZE: $min"
12160                         (( $max == $PAGE_SIZE )) ||
12161                                 error "max is not $PAGE_SIZE: $max"
12162                         (( $sum == $PAGE_SIZE * 2 )) ||
12163                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12164                         ;;
12165                 read|write)
12166                         [[ "$unit" =~ "usec" ]] ||
12167                                 error "unit is not 'usec': $unit"
12168                         ;;
12169                 *)      ;;
12170                 esac
12171         done < $TMP/$tfile.tmp
12172
12173         #check that we actually got some stats
12174         [ "$read_bytes" ] || error "Missing read_bytes stats"
12175         [ "$write_bytes" ] || error "Missing write_bytes stats"
12176         [ "$read_bytes" != 0 ] || error "no read done"
12177         [ "$write_bytes" != 0 ] || error "no write done"
12178 }
12179 run_test 127b "verify the llite client stats are sane"
12180
12181 test_127c() { # LU-12394
12182         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12183         local size
12184         local bsize
12185         local reads
12186         local writes
12187         local count
12188
12189         $LCTL set_param llite.*.extents_stats=1
12190         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12191
12192         # Use two stripes so there is enough space in default config
12193         $LFS setstripe -c 2 $DIR/$tfile
12194
12195         # Extent stats start at 0-4K and go in power of two buckets
12196         # LL_HIST_START = 12 --> 2^12 = 4K
12197         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12198         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12199         # small configs
12200         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12201                 do
12202                 # Write and read, 2x each, second time at a non-zero offset
12203                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12204                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12205                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12206                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12207                 rm -f $DIR/$tfile
12208         done
12209
12210         $LCTL get_param llite.*.extents_stats
12211
12212         count=2
12213         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12214                 do
12215                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12216                                 grep -m 1 $bsize)
12217                 reads=$(echo $bucket | awk '{print $5}')
12218                 writes=$(echo $bucket | awk '{print $9}')
12219                 [ "$reads" -eq $count ] ||
12220                         error "$reads reads in < $bsize bucket, expect $count"
12221                 [ "$writes" -eq $count ] ||
12222                         error "$writes writes in < $bsize bucket, expect $count"
12223         done
12224
12225         # Test mmap write and read
12226         $LCTL set_param llite.*.extents_stats=c
12227         size=512
12228         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12229         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12230         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12231
12232         $LCTL get_param llite.*.extents_stats
12233
12234         count=$(((size*1024) / PAGE_SIZE))
12235
12236         bsize=$((2 * PAGE_SIZE / 1024))K
12237
12238         bucket=$($LCTL get_param -n llite.*.extents_stats |
12239                         grep -m 1 $bsize)
12240         reads=$(echo $bucket | awk '{print $5}')
12241         writes=$(echo $bucket | awk '{print $9}')
12242         # mmap writes fault in the page first, creating an additonal read
12243         [ "$reads" -eq $((2 * count)) ] ||
12244                 error "$reads reads in < $bsize bucket, expect $count"
12245         [ "$writes" -eq $count ] ||
12246                 error "$writes writes in < $bsize bucket, expect $count"
12247 }
12248 run_test 127c "test llite extent stats with regular & mmap i/o"
12249
12250 test_128() { # bug 15212
12251         touch $DIR/$tfile
12252         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12253                 find $DIR/$tfile
12254                 find $DIR/$tfile
12255         EOF
12256
12257         result=$(grep error $TMP/$tfile.log)
12258         rm -f $DIR/$tfile $TMP/$tfile.log
12259         [ -z "$result" ] ||
12260                 error "consecutive find's under interactive lfs failed"
12261 }
12262 run_test 128 "interactive lfs for 2 consecutive find's"
12263
12264 set_dir_limits () {
12265         local mntdev
12266         local canondev
12267         local node
12268
12269         local ldproc=/proc/fs/ldiskfs
12270         local facets=$(get_facets MDS)
12271
12272         for facet in ${facets//,/ }; do
12273                 canondev=$(ldiskfs_canon \
12274                            *.$(convert_facet2label $facet).mntdev $facet)
12275                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12276                         ldproc=/sys/fs/ldiskfs
12277                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12278                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12279         done
12280 }
12281
12282 check_mds_dmesg() {
12283         local facets=$(get_facets MDS)
12284         for facet in ${facets//,/ }; do
12285                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12286         done
12287         return 1
12288 }
12289
12290 test_129() {
12291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12292         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12293                 skip "Need MDS version with at least 2.5.56"
12294         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12295                 skip_env "ldiskfs only test"
12296         fi
12297         remote_mds_nodsh && skip "remote MDS with nodsh"
12298
12299         local ENOSPC=28
12300         local has_warning=false
12301
12302         rm -rf $DIR/$tdir
12303         mkdir -p $DIR/$tdir
12304
12305         # block size of mds1
12306         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12307         set_dir_limits $maxsize $((maxsize * 6 / 8))
12308         stack_trap "set_dir_limits 0 0"
12309         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12310         local dirsize=$(stat -c%s "$DIR/$tdir")
12311         local nfiles=0
12312         while (( $dirsize <= $maxsize )); do
12313                 $MCREATE $DIR/$tdir/file_base_$nfiles
12314                 rc=$?
12315                 # check two errors:
12316                 # ENOSPC for ext4 max_dir_size, which has been used since
12317                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12318                 if (( rc == ENOSPC )); then
12319                         set_dir_limits 0 0
12320                         echo "rc=$rc returned as expected after $nfiles files"
12321
12322                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12323                                 error "create failed w/o dir size limit"
12324
12325                         # messages may be rate limited if test is run repeatedly
12326                         check_mds_dmesg '"is approaching max"' ||
12327                                 echo "warning message should be output"
12328                         check_mds_dmesg '"has reached max"' ||
12329                                 echo "reached message should be output"
12330
12331                         dirsize=$(stat -c%s "$DIR/$tdir")
12332
12333                         [[ $dirsize -ge $maxsize ]] && return 0
12334                         error "dirsize $dirsize < $maxsize after $nfiles files"
12335                 elif (( rc != 0 )); then
12336                         break
12337                 fi
12338                 nfiles=$((nfiles + 1))
12339                 dirsize=$(stat -c%s "$DIR/$tdir")
12340         done
12341
12342         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12343 }
12344 run_test 129 "test directory size limit ========================"
12345
12346 OLDIFS="$IFS"
12347 cleanup_130() {
12348         trap 0
12349         IFS="$OLDIFS"
12350 }
12351
12352 test_130a() {
12353         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12354         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12355
12356         trap cleanup_130 EXIT RETURN
12357
12358         local fm_file=$DIR/$tfile
12359         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12360         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12361                 error "dd failed for $fm_file"
12362
12363         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12364         filefrag -ves $fm_file
12365         RC=$?
12366         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12367                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12368         [ $RC != 0 ] && error "filefrag $fm_file failed"
12369
12370         filefrag_op=$(filefrag -ve -k $fm_file |
12371                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12372         lun=$($LFS getstripe -i $fm_file)
12373
12374         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12375         IFS=$'\n'
12376         tot_len=0
12377         for line in $filefrag_op
12378         do
12379                 frag_lun=`echo $line | cut -d: -f5`
12380                 ext_len=`echo $line | cut -d: -f4`
12381                 if (( $frag_lun != $lun )); then
12382                         cleanup_130
12383                         error "FIEMAP on 1-stripe file($fm_file) failed"
12384                         return
12385                 fi
12386                 (( tot_len += ext_len ))
12387         done
12388
12389         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12390                 cleanup_130
12391                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12392                 return
12393         fi
12394
12395         cleanup_130
12396
12397         echo "FIEMAP on single striped file succeeded"
12398 }
12399 run_test 130a "FIEMAP (1-stripe file)"
12400
12401 test_130b() {
12402         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12403
12404         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12405         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12406
12407         trap cleanup_130 EXIT RETURN
12408
12409         local fm_file=$DIR/$tfile
12410         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12411                         error "setstripe on $fm_file"
12412         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12413                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12414
12415         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12416                 error "dd failed on $fm_file"
12417
12418         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12419         filefrag_op=$(filefrag -ve -k $fm_file |
12420                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12421
12422         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12423                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12424
12425         IFS=$'\n'
12426         tot_len=0
12427         num_luns=1
12428         for line in $filefrag_op
12429         do
12430                 frag_lun=$(echo $line | cut -d: -f5 |
12431                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12432                 ext_len=$(echo $line | cut -d: -f4)
12433                 if (( $frag_lun != $last_lun )); then
12434                         if (( tot_len != 1024 )); then
12435                                 cleanup_130
12436                                 error "FIEMAP on $fm_file failed; returned " \
12437                                 "len $tot_len for OST $last_lun instead of 1024"
12438                                 return
12439                         else
12440                                 (( num_luns += 1 ))
12441                                 tot_len=0
12442                         fi
12443                 fi
12444                 (( tot_len += ext_len ))
12445                 last_lun=$frag_lun
12446         done
12447         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12448                 cleanup_130
12449                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12450                         "luns or wrong len for OST $last_lun"
12451                 return
12452         fi
12453
12454         cleanup_130
12455
12456         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12457 }
12458 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12459
12460 test_130c() {
12461         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12462
12463         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12464         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12465
12466         trap cleanup_130 EXIT RETURN
12467
12468         local fm_file=$DIR/$tfile
12469         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12470         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12471                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12472
12473         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12474                         error "dd failed on $fm_file"
12475
12476         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12477         filefrag_op=$(filefrag -ve -k $fm_file |
12478                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12479
12480         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12481                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12482
12483         IFS=$'\n'
12484         tot_len=0
12485         num_luns=1
12486         for line in $filefrag_op
12487         do
12488                 frag_lun=$(echo $line | cut -d: -f5 |
12489                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12490                 ext_len=$(echo $line | cut -d: -f4)
12491                 if (( $frag_lun != $last_lun )); then
12492                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12493                         if (( logical != 512 )); then
12494                                 cleanup_130
12495                                 error "FIEMAP on $fm_file failed; returned " \
12496                                 "logical start for lun $logical instead of 512"
12497                                 return
12498                         fi
12499                         if (( tot_len != 512 )); then
12500                                 cleanup_130
12501                                 error "FIEMAP on $fm_file failed; returned " \
12502                                 "len $tot_len for OST $last_lun instead of 1024"
12503                                 return
12504                         else
12505                                 (( num_luns += 1 ))
12506                                 tot_len=0
12507                         fi
12508                 fi
12509                 (( tot_len += ext_len ))
12510                 last_lun=$frag_lun
12511         done
12512         if (( num_luns != 2 || tot_len != 512 )); then
12513                 cleanup_130
12514                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12515                         "luns or wrong len for OST $last_lun"
12516                 return
12517         fi
12518
12519         cleanup_130
12520
12521         echo "FIEMAP on 2-stripe file with hole succeeded"
12522 }
12523 run_test 130c "FIEMAP (2-stripe file with hole)"
12524
12525 test_130d() {
12526         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12527
12528         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12529         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12530
12531         trap cleanup_130 EXIT RETURN
12532
12533         local fm_file=$DIR/$tfile
12534         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12535                         error "setstripe on $fm_file"
12536         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12537                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12538
12539         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12540         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12541                 error "dd failed on $fm_file"
12542
12543         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12544         filefrag_op=$(filefrag -ve -k $fm_file |
12545                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12546
12547         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12548                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12549
12550         IFS=$'\n'
12551         tot_len=0
12552         num_luns=1
12553         for line in $filefrag_op
12554         do
12555                 frag_lun=$(echo $line | cut -d: -f5 |
12556                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12557                 ext_len=$(echo $line | cut -d: -f4)
12558                 if (( $frag_lun != $last_lun )); then
12559                         if (( tot_len != 1024 )); then
12560                                 cleanup_130
12561                                 error "FIEMAP on $fm_file failed; returned " \
12562                                 "len $tot_len for OST $last_lun instead of 1024"
12563                                 return
12564                         else
12565                                 (( num_luns += 1 ))
12566                                 tot_len=0
12567                         fi
12568                 fi
12569                 (( tot_len += ext_len ))
12570                 last_lun=$frag_lun
12571         done
12572         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12573                 cleanup_130
12574                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12575                         "luns or wrong len for OST $last_lun"
12576                 return
12577         fi
12578
12579         cleanup_130
12580
12581         echo "FIEMAP on N-stripe file succeeded"
12582 }
12583 run_test 130d "FIEMAP (N-stripe file)"
12584
12585 test_130e() {
12586         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12587
12588         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12589         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12590
12591         trap cleanup_130 EXIT RETURN
12592
12593         local fm_file=$DIR/$tfile
12594         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12595         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12596                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12597
12598         NUM_BLKS=512
12599         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12600         for ((i = 0; i < $NUM_BLKS; i++))
12601         do
12602                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
12603         done
12604
12605         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12606         filefrag_op=$(filefrag -ve -k $fm_file |
12607                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12608
12609         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12610                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12611
12612         IFS=$'\n'
12613         tot_len=0
12614         num_luns=1
12615         for line in $filefrag_op
12616         do
12617                 frag_lun=$(echo $line | cut -d: -f5 |
12618                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12619                 ext_len=$(echo $line | cut -d: -f4)
12620                 if (( $frag_lun != $last_lun )); then
12621                         if (( tot_len != $EXPECTED_LEN )); then
12622                                 cleanup_130
12623                                 error "FIEMAP on $fm_file failed; returned " \
12624                                 "len $tot_len for OST $last_lun instead " \
12625                                 "of $EXPECTED_LEN"
12626                                 return
12627                         else
12628                                 (( num_luns += 1 ))
12629                                 tot_len=0
12630                         fi
12631                 fi
12632                 (( tot_len += ext_len ))
12633                 last_lun=$frag_lun
12634         done
12635         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12636                 cleanup_130
12637                 error "FIEMAP on $fm_file failed; returned wrong number " \
12638                         "of luns or wrong len for OST $last_lun"
12639                 return
12640         fi
12641
12642         cleanup_130
12643
12644         echo "FIEMAP with continuation calls succeeded"
12645 }
12646 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12647
12648 test_130f() {
12649         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12650         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12651
12652         local fm_file=$DIR/$tfile
12653         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12654                 error "multiop create with lov_delay_create on $fm_file"
12655
12656         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12657         filefrag_extents=$(filefrag -vek $fm_file |
12658                            awk '/extents? found/ { print $2 }')
12659         if [[ "$filefrag_extents" != "0" ]]; then
12660                 error "FIEMAP on $fm_file failed; " \
12661                       "returned $filefrag_extents expected 0"
12662         fi
12663
12664         rm -f $fm_file
12665 }
12666 run_test 130f "FIEMAP (unstriped file)"
12667
12668 # Test for writev/readv
12669 test_131a() {
12670         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12671                 error "writev test failed"
12672         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12673                 error "readv failed"
12674         rm -f $DIR/$tfile
12675 }
12676 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12677
12678 test_131b() {
12679         local fsize=$((524288 + 1048576 + 1572864))
12680         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12681                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12682                         error "append writev test failed"
12683
12684         ((fsize += 1572864 + 1048576))
12685         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12686                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12687                         error "append writev test failed"
12688         rm -f $DIR/$tfile
12689 }
12690 run_test 131b "test append writev"
12691
12692 test_131c() {
12693         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12694         error "NOT PASS"
12695 }
12696 run_test 131c "test read/write on file w/o objects"
12697
12698 test_131d() {
12699         rwv -f $DIR/$tfile -w -n 1 1572864
12700         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12701         if [ "$NOB" != 1572864 ]; then
12702                 error "Short read filed: read $NOB bytes instead of 1572864"
12703         fi
12704         rm -f $DIR/$tfile
12705 }
12706 run_test 131d "test short read"
12707
12708 test_131e() {
12709         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12710         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12711         error "read hitting hole failed"
12712         rm -f $DIR/$tfile
12713 }
12714 run_test 131e "test read hitting hole"
12715
12716 check_stats() {
12717         local facet=$1
12718         local op=$2
12719         local want=${3:-0}
12720         local res
12721
12722         case $facet in
12723         mds*) res=$(do_facet $facet \
12724                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12725                  ;;
12726         ost*) res=$(do_facet $facet \
12727                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12728                  ;;
12729         *) error "Wrong facet '$facet'" ;;
12730         esac
12731         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12732         # if the argument $3 is zero, it means any stat increment is ok.
12733         if [[ $want -gt 0 ]]; then
12734                 local count=$(echo $res | awk '{ print $2 }')
12735                 [[ $count -ne $want ]] &&
12736                         error "The $op counter on $facet is $count, not $want"
12737         fi
12738 }
12739
12740 test_133a() {
12741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12742         remote_ost_nodsh && skip "remote OST with nodsh"
12743         remote_mds_nodsh && skip "remote MDS with nodsh"
12744         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12745                 skip_env "MDS doesn't support rename stats"
12746
12747         local testdir=$DIR/${tdir}/stats_testdir
12748
12749         mkdir -p $DIR/${tdir}
12750
12751         # clear stats.
12752         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12753         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12754
12755         # verify mdt stats first.
12756         mkdir ${testdir} || error "mkdir failed"
12757         check_stats $SINGLEMDS "mkdir" 1
12758         touch ${testdir}/${tfile} || error "touch failed"
12759         check_stats $SINGLEMDS "open" 1
12760         check_stats $SINGLEMDS "close" 1
12761         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12762                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12763                 check_stats $SINGLEMDS "mknod" 2
12764         }
12765         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12766         check_stats $SINGLEMDS "unlink" 1
12767         rm -f ${testdir}/${tfile} || error "file remove failed"
12768         check_stats $SINGLEMDS "unlink" 2
12769
12770         # remove working dir and check mdt stats again.
12771         rmdir ${testdir} || error "rmdir failed"
12772         check_stats $SINGLEMDS "rmdir" 1
12773
12774         local testdir1=$DIR/${tdir}/stats_testdir1
12775         mkdir -p ${testdir}
12776         mkdir -p ${testdir1}
12777         touch ${testdir1}/test1
12778         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12779         check_stats $SINGLEMDS "crossdir_rename" 1
12780
12781         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12782         check_stats $SINGLEMDS "samedir_rename" 1
12783
12784         rm -rf $DIR/${tdir}
12785 }
12786 run_test 133a "Verifying MDT stats ========================================"
12787
12788 test_133b() {
12789         local res
12790
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         mkdir -p ${testdir} || error "mkdir failed"
12798         touch ${testdir}/${tfile} || error "touch failed"
12799         cancel_lru_locks mdc
12800
12801         # clear stats.
12802         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12803         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12804
12805         # extra mdt stats verification.
12806         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12807         check_stats $SINGLEMDS "setattr" 1
12808         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12809         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12810         then            # LU-1740
12811                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12812                 check_stats $SINGLEMDS "getattr" 1
12813         fi
12814         rm -rf $DIR/${tdir}
12815
12816         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12817         # so the check below is not reliable
12818         [ $MDSCOUNT -eq 1 ] || return 0
12819
12820         # Sleep to avoid a cached response.
12821         #define OBD_STATFS_CACHE_SECONDS 1
12822         sleep 2
12823         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12824         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12825         $LFS df || error "lfs failed"
12826         check_stats $SINGLEMDS "statfs" 1
12827
12828         # check aggregated statfs (LU-10018)
12829         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12830                 return 0
12831         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12832                 return 0
12833         sleep 2
12834         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12835         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12836         df $DIR
12837         check_stats $SINGLEMDS "statfs" 1
12838
12839         # We want to check that the client didn't send OST_STATFS to
12840         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12841         # extra care is needed here.
12842         if remote_mds; then
12843                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12844                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12845
12846                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12847                 [ "$res" ] && error "OST got STATFS"
12848         fi
12849
12850         return 0
12851 }
12852 run_test 133b "Verifying extra MDT stats =================================="
12853
12854 test_133c() {
12855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12856         remote_ost_nodsh && skip "remote OST with nodsh"
12857         remote_mds_nodsh && skip "remote MDS with nodsh"
12858
12859         local testdir=$DIR/$tdir/stats_testdir
12860
12861         test_mkdir -p $testdir
12862
12863         # verify obdfilter stats.
12864         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12865         sync
12866         cancel_lru_locks osc
12867         wait_delete_completed
12868
12869         # clear stats.
12870         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12871         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12872
12873         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12874                 error "dd failed"
12875         sync
12876         cancel_lru_locks osc
12877         check_stats ost1 "write" 1
12878
12879         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12880         check_stats ost1 "read" 1
12881
12882         > $testdir/$tfile || error "truncate failed"
12883         check_stats ost1 "punch" 1
12884
12885         rm -f $testdir/$tfile || error "file remove failed"
12886         wait_delete_completed
12887         check_stats ost1 "destroy" 1
12888
12889         rm -rf $DIR/$tdir
12890 }
12891 run_test 133c "Verifying OST stats ========================================"
12892
12893 order_2() {
12894         local value=$1
12895         local orig=$value
12896         local order=1
12897
12898         while [ $value -ge 2 ]; do
12899                 order=$((order*2))
12900                 value=$((value/2))
12901         done
12902
12903         if [ $orig -gt $order ]; then
12904                 order=$((order*2))
12905         fi
12906         echo $order
12907 }
12908
12909 size_in_KMGT() {
12910     local value=$1
12911     local size=('K' 'M' 'G' 'T');
12912     local i=0
12913     local size_string=$value
12914
12915     while [ $value -ge 1024 ]; do
12916         if [ $i -gt 3 ]; then
12917             #T is the biggest unit we get here, if that is bigger,
12918             #just return XXXT
12919             size_string=${value}T
12920             break
12921         fi
12922         value=$((value >> 10))
12923         if [ $value -lt 1024 ]; then
12924             size_string=${value}${size[$i]}
12925             break
12926         fi
12927         i=$((i + 1))
12928     done
12929
12930     echo $size_string
12931 }
12932
12933 get_rename_size() {
12934         local size=$1
12935         local context=${2:-.}
12936         local sample=$(do_facet $SINGLEMDS $LCTL \
12937                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12938                 grep -A1 $context |
12939                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12940         echo $sample
12941 }
12942
12943 test_133d() {
12944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12945         remote_ost_nodsh && skip "remote OST with nodsh"
12946         remote_mds_nodsh && skip "remote MDS with nodsh"
12947         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12948                 skip_env "MDS doesn't support rename stats"
12949
12950         local testdir1=$DIR/${tdir}/stats_testdir1
12951         local testdir2=$DIR/${tdir}/stats_testdir2
12952         mkdir -p $DIR/${tdir}
12953
12954         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12955
12956         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12957         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12958
12959         createmany -o $testdir1/test 512 || error "createmany failed"
12960
12961         # check samedir rename size
12962         mv ${testdir1}/test0 ${testdir1}/test_0
12963
12964         local testdir1_size=$(ls -l $DIR/${tdir} |
12965                 awk '/stats_testdir1/ {print $5}')
12966         local testdir2_size=$(ls -l $DIR/${tdir} |
12967                 awk '/stats_testdir2/ {print $5}')
12968
12969         testdir1_size=$(order_2 $testdir1_size)
12970         testdir2_size=$(order_2 $testdir2_size)
12971
12972         testdir1_size=$(size_in_KMGT $testdir1_size)
12973         testdir2_size=$(size_in_KMGT $testdir2_size)
12974
12975         echo "source rename dir size: ${testdir1_size}"
12976         echo "target rename dir size: ${testdir2_size}"
12977
12978         local cmd="do_facet $SINGLEMDS $LCTL "
12979         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
12980
12981         eval $cmd || error "$cmd failed"
12982         local samedir=$($cmd | grep 'same_dir')
12983         local same_sample=$(get_rename_size $testdir1_size)
12984         [ -z "$samedir" ] && error "samedir_rename_size count error"
12985         [[ $same_sample -eq 1 ]] ||
12986                 error "samedir_rename_size error $same_sample"
12987         echo "Check same dir rename stats success"
12988
12989         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12990
12991         # check crossdir rename size
12992         mv ${testdir1}/test_0 ${testdir2}/test_0
12993
12994         testdir1_size=$(ls -l $DIR/${tdir} |
12995                 awk '/stats_testdir1/ {print $5}')
12996         testdir2_size=$(ls -l $DIR/${tdir} |
12997                 awk '/stats_testdir2/ {print $5}')
12998
12999         testdir1_size=$(order_2 $testdir1_size)
13000         testdir2_size=$(order_2 $testdir2_size)
13001
13002         testdir1_size=$(size_in_KMGT $testdir1_size)
13003         testdir2_size=$(size_in_KMGT $testdir2_size)
13004
13005         echo "source rename dir size: ${testdir1_size}"
13006         echo "target rename dir size: ${testdir2_size}"
13007
13008         eval $cmd || error "$cmd failed"
13009         local crossdir=$($cmd | grep 'crossdir')
13010         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13011         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13012         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13013         [[ $src_sample -eq 1 ]] ||
13014                 error "crossdir_rename_size error $src_sample"
13015         [[ $tgt_sample -eq 1 ]] ||
13016                 error "crossdir_rename_size error $tgt_sample"
13017         echo "Check cross dir rename stats success"
13018         rm -rf $DIR/${tdir}
13019 }
13020 run_test 133d "Verifying rename_stats ========================================"
13021
13022 test_133e() {
13023         remote_mds_nodsh && skip "remote MDS with nodsh"
13024         remote_ost_nodsh && skip "remote OST with nodsh"
13025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13026
13027         local testdir=$DIR/${tdir}/stats_testdir
13028         local ctr f0 f1 bs=32768 count=42 sum
13029
13030         mkdir -p ${testdir} || error "mkdir failed"
13031
13032         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13033
13034         for ctr in {write,read}_bytes; do
13035                 sync
13036                 cancel_lru_locks osc
13037
13038                 do_facet ost1 $LCTL set_param -n \
13039                         "obdfilter.*.exports.clear=clear"
13040
13041                 if [ $ctr = write_bytes ]; then
13042                         f0=/dev/zero
13043                         f1=${testdir}/${tfile}
13044                 else
13045                         f0=${testdir}/${tfile}
13046                         f1=/dev/null
13047                 fi
13048
13049                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13050                         error "dd failed"
13051                 sync
13052                 cancel_lru_locks osc
13053
13054                 sum=$(do_facet ost1 $LCTL get_param \
13055                         "obdfilter.*.exports.*.stats" |
13056                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13057                                 $1 == ctr { sum += $7 }
13058                                 END { printf("%0.0f", sum) }')
13059
13060                 if ((sum != bs * count)); then
13061                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13062                 fi
13063         done
13064
13065         rm -rf $DIR/${tdir}
13066 }
13067 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13068
13069 test_133f() {
13070         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13071                 skip "too old lustre for get_param -R ($facet_ver)"
13072
13073         # verifying readability.
13074         $LCTL get_param -R '*' &> /dev/null
13075
13076         # Verifing writability with badarea_io.
13077         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13078                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13079                 error "client badarea_io failed"
13080
13081         # remount the FS in case writes/reads /proc break the FS
13082         cleanup || error "failed to unmount"
13083         setup || error "failed to setup"
13084 }
13085 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13086
13087 test_133g() {
13088         remote_mds_nodsh && skip "remote MDS with nodsh"
13089         remote_ost_nodsh && skip "remote OST with nodsh"
13090
13091         local facet
13092         for facet in mds1 ost1; do
13093                 local facet_ver=$(lustre_version_code $facet)
13094                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13095                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13096                 else
13097                         log "$facet: too old lustre for get_param -R"
13098                 fi
13099                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13100                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13101                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13102                                 xargs badarea_io" ||
13103                                         error "$facet badarea_io failed"
13104                 else
13105                         skip_noexit "$facet: too old lustre for get_param -R"
13106                 fi
13107         done
13108
13109         # remount the FS in case writes/reads /proc break the FS
13110         cleanup || error "failed to unmount"
13111         setup || error "failed to setup"
13112 }
13113 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13114
13115 test_133h() {
13116         remote_mds_nodsh && skip "remote MDS with nodsh"
13117         remote_ost_nodsh && skip "remote OST with nodsh"
13118         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13119                 skip "Need MDS version at least 2.9.54"
13120
13121         local facet
13122         for facet in client mds1 ost1; do
13123                 # Get the list of files that are missing the terminating newline
13124                 local plist=$(do_facet $facet
13125                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13126                 local ent
13127                 for ent in $plist; do
13128                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13129                                 awk -v FS='\v' -v RS='\v\v' \
13130                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13131                                         print FILENAME}'" 2>/dev/null)
13132                         [ -z $missing ] || {
13133                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13134                                 error "file does not end with newline: $facet-$ent"
13135                         }
13136                 done
13137         done
13138 }
13139 run_test 133h "Proc files should end with newlines"
13140
13141 test_134a() {
13142         remote_mds_nodsh && skip "remote MDS with nodsh"
13143         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13144                 skip "Need MDS version at least 2.7.54"
13145
13146         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13147         cancel_lru_locks mdc
13148
13149         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13150         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13151         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13152
13153         local nr=1000
13154         createmany -o $DIR/$tdir/f $nr ||
13155                 error "failed to create $nr files in $DIR/$tdir"
13156         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13157
13158         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13159         do_facet mds1 $LCTL set_param fail_loc=0x327
13160         do_facet mds1 $LCTL set_param fail_val=500
13161         touch $DIR/$tdir/m
13162
13163         echo "sleep 10 seconds ..."
13164         sleep 10
13165         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13166
13167         do_facet mds1 $LCTL set_param fail_loc=0
13168         do_facet mds1 $LCTL set_param fail_val=0
13169         [ $lck_cnt -lt $unused ] ||
13170                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13171
13172         rm $DIR/$tdir/m
13173         unlinkmany $DIR/$tdir/f $nr
13174 }
13175 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13176
13177 test_134b() {
13178         remote_mds_nodsh && skip "remote MDS with nodsh"
13179         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13180                 skip "Need MDS version at least 2.7.54"
13181
13182         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13183         cancel_lru_locks mdc
13184
13185         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13186                         ldlm.lock_reclaim_threshold_mb)
13187         # disable reclaim temporarily
13188         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13189
13190         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13191         do_facet mds1 $LCTL set_param fail_loc=0x328
13192         do_facet mds1 $LCTL set_param fail_val=500
13193
13194         $LCTL set_param debug=+trace
13195
13196         local nr=600
13197         createmany -o $DIR/$tdir/f $nr &
13198         local create_pid=$!
13199
13200         echo "Sleep $TIMEOUT seconds ..."
13201         sleep $TIMEOUT
13202         if ! ps -p $create_pid  > /dev/null 2>&1; then
13203                 do_facet mds1 $LCTL set_param fail_loc=0
13204                 do_facet mds1 $LCTL set_param fail_val=0
13205                 do_facet mds1 $LCTL set_param \
13206                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13207                 error "createmany finished incorrectly!"
13208         fi
13209         do_facet mds1 $LCTL set_param fail_loc=0
13210         do_facet mds1 $LCTL set_param fail_val=0
13211         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13212         wait $create_pid || return 1
13213
13214         unlinkmany $DIR/$tdir/f $nr
13215 }
13216 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13217
13218 test_135() {
13219         remote_mds_nodsh && skip "remote MDS with nodsh"
13220         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13221                 skip "Need MDS version at least 2.13.50"
13222         local fname
13223
13224         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13225
13226 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13227         #set only one record at plain llog
13228         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13229
13230         #fill already existed plain llog each 64767
13231         #wrapping whole catalog
13232         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13233
13234         createmany -o $DIR/$tdir/$tfile_ 64700
13235         for (( i = 0; i < 64700; i = i + 2 ))
13236         do
13237                 rm $DIR/$tdir/$tfile_$i &
13238                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13239                 local pid=$!
13240                 wait $pid
13241         done
13242
13243         #waiting osp synchronization
13244         wait_delete_completed
13245 }
13246 run_test 135 "Race catalog processing"
13247
13248 test_136() {
13249         remote_mds_nodsh && skip "remote MDS with nodsh"
13250         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13251                 skip "Need MDS version at least 2.13.50"
13252         local fname
13253
13254         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13255         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13256         #set only one record at plain llog
13257 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13258         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13259
13260         #fill already existed 2 plain llogs each 64767
13261         #wrapping whole catalog
13262         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13263         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13264         wait_delete_completed
13265
13266         createmany -o $DIR/$tdir/$tfile_ 10
13267         sleep 25
13268
13269         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13270         for (( i = 0; i < 10; i = i + 3 ))
13271         do
13272                 rm $DIR/$tdir/$tfile_$i &
13273                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13274                 local pid=$!
13275                 wait $pid
13276                 sleep 7
13277                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13278         done
13279
13280         #waiting osp synchronization
13281         wait_delete_completed
13282 }
13283 run_test 136 "Race catalog processing 2"
13284
13285 test_140() { #bug-17379
13286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13287
13288         test_mkdir $DIR/$tdir
13289         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13290         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13291
13292         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13293         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13294         local i=0
13295         while i=$((i + 1)); do
13296                 test_mkdir $i
13297                 cd $i || error "Changing to $i"
13298                 ln -s ../stat stat || error "Creating stat symlink"
13299                 # Read the symlink until ELOOP present,
13300                 # not LBUGing the system is considered success,
13301                 # we didn't overrun the stack.
13302                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13303                 if [ $ret -ne 0 ]; then
13304                         if [ $ret -eq 40 ]; then
13305                                 break  # -ELOOP
13306                         else
13307                                 error "Open stat symlink"
13308                                         return
13309                         fi
13310                 fi
13311         done
13312         i=$((i - 1))
13313         echo "The symlink depth = $i"
13314         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13315                 error "Invalid symlink depth"
13316
13317         # Test recursive symlink
13318         ln -s symlink_self symlink_self
13319         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13320         echo "open symlink_self returns $ret"
13321         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13322 }
13323 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13324
13325 test_150a() {
13326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13327
13328         local TF="$TMP/$tfile"
13329
13330         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13331         cp $TF $DIR/$tfile
13332         cancel_lru_locks $OSC
13333         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13334         remount_client $MOUNT
13335         df -P $MOUNT
13336         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13337
13338         $TRUNCATE $TF 6000
13339         $TRUNCATE $DIR/$tfile 6000
13340         cancel_lru_locks $OSC
13341         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13342
13343         echo "12345" >>$TF
13344         echo "12345" >>$DIR/$tfile
13345         cancel_lru_locks $OSC
13346         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13347
13348         echo "12345" >>$TF
13349         echo "12345" >>$DIR/$tfile
13350         cancel_lru_locks $OSC
13351         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13352
13353         rm -f $TF
13354         true
13355 }
13356 run_test 150a "truncate/append tests"
13357
13358 test_150b() {
13359         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13360         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13361                 skip "Need OST version at least 2.13.53"
13362         touch $DIR/$tfile
13363         check_fallocate $DIR/$tfile || error "fallocate failed"
13364 }
13365 run_test 150b "Verify fallocate (prealloc) functionality"
13366
13367 test_150c() {
13368         local bytes
13369         local want
13370
13371         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13372         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13373                 skip "Need OST version at least 2.13.53"
13374
13375         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13376         fallocate -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13377         sync; sync_all_data
13378         cancel_lru_locks $OSC
13379         sleep 5
13380         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13381         want=$((OSTCOUNT * 1048576))
13382
13383         # Must allocate all requested space, not more than 5% extra
13384         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13385                 error "bytes $bytes is not $want"
13386 }
13387 run_test 150c "Verify fallocate Size and Blocks"
13388
13389 test_150d() {
13390         local bytes
13391         local want
13392
13393         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13394         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13395                 skip "Need OST version at least 2.13.53"
13396
13397         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13398         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13399         sync; sync_all_data
13400         cancel_lru_locks $OSC
13401         sleep 5
13402         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13403         want=$((OSTCOUNT * 1048576))
13404
13405         # Must allocate all requested space, not more than 5% extra
13406         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13407                 error "bytes $bytes is not $want"
13408 }
13409 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13410
13411 #LU-2902 roc_hit was not able to read all values from lproc
13412 function roc_hit_init() {
13413         local list=$(comma_list $(osts_nodes))
13414         local dir=$DIR/$tdir-check
13415         local file=$dir/$tfile
13416         local BEFORE
13417         local AFTER
13418         local idx
13419
13420         test_mkdir $dir
13421         #use setstripe to do a write to every ost
13422         for i in $(seq 0 $((OSTCOUNT-1))); do
13423                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13424                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13425                 idx=$(printf %04x $i)
13426                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13427                         awk '$1 == "cache_access" {sum += $7}
13428                                 END { printf("%0.0f", sum) }')
13429
13430                 cancel_lru_locks osc
13431                 cat $file >/dev/null
13432
13433                 AFTER=$(get_osd_param $list *OST*$idx stats |
13434                         awk '$1 == "cache_access" {sum += $7}
13435                                 END { printf("%0.0f", sum) }')
13436
13437                 echo BEFORE:$BEFORE AFTER:$AFTER
13438                 if ! let "AFTER - BEFORE == 4"; then
13439                         rm -rf $dir
13440                         error "roc_hit is not safe to use"
13441                 fi
13442                 rm $file
13443         done
13444
13445         rm -rf $dir
13446 }
13447
13448 function roc_hit() {
13449         local list=$(comma_list $(osts_nodes))
13450         echo $(get_osd_param $list '' stats |
13451                 awk '$1 == "cache_hit" {sum += $7}
13452                         END { printf("%0.0f", sum) }')
13453 }
13454
13455 function set_cache() {
13456         local on=1
13457
13458         if [ "$2" == "off" ]; then
13459                 on=0;
13460         fi
13461         local list=$(comma_list $(osts_nodes))
13462         set_osd_param $list '' $1_cache_enable $on
13463
13464         cancel_lru_locks osc
13465 }
13466
13467 test_151() {
13468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13469         remote_ost_nodsh && skip "remote OST with nodsh"
13470
13471         local CPAGES=3
13472         local list=$(comma_list $(osts_nodes))
13473
13474         # check whether obdfilter is cache capable at all
13475         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13476                 skip "not cache-capable obdfilter"
13477         fi
13478
13479         # check cache is enabled on all obdfilters
13480         if get_osd_param $list '' read_cache_enable | grep 0; then
13481                 skip "oss cache is disabled"
13482         fi
13483
13484         set_osd_param $list '' writethrough_cache_enable 1
13485
13486         # check write cache is enabled on all obdfilters
13487         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13488                 skip "oss write cache is NOT enabled"
13489         fi
13490
13491         roc_hit_init
13492
13493         #define OBD_FAIL_OBD_NO_LRU  0x609
13494         do_nodes $list $LCTL set_param fail_loc=0x609
13495
13496         # pages should be in the case right after write
13497         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13498                 error "dd failed"
13499
13500         local BEFORE=$(roc_hit)
13501         cancel_lru_locks osc
13502         cat $DIR/$tfile >/dev/null
13503         local AFTER=$(roc_hit)
13504
13505         do_nodes $list $LCTL set_param fail_loc=0
13506
13507         if ! let "AFTER - BEFORE == CPAGES"; then
13508                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13509         fi
13510
13511         cancel_lru_locks osc
13512         # invalidates OST cache
13513         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13514         set_osd_param $list '' read_cache_enable 0
13515         cat $DIR/$tfile >/dev/null
13516
13517         # now data shouldn't be found in the cache
13518         BEFORE=$(roc_hit)
13519         cancel_lru_locks osc
13520         cat $DIR/$tfile >/dev/null
13521         AFTER=$(roc_hit)
13522         if let "AFTER - BEFORE != 0"; then
13523                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13524         fi
13525
13526         set_osd_param $list '' read_cache_enable 1
13527         rm -f $DIR/$tfile
13528 }
13529 run_test 151 "test cache on oss and controls ==============================="
13530
13531 test_152() {
13532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13533
13534         local TF="$TMP/$tfile"
13535
13536         # simulate ENOMEM during write
13537 #define OBD_FAIL_OST_NOMEM      0x226
13538         lctl set_param fail_loc=0x80000226
13539         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13540         cp $TF $DIR/$tfile
13541         sync || error "sync failed"
13542         lctl set_param fail_loc=0
13543
13544         # discard client's cache
13545         cancel_lru_locks osc
13546
13547         # simulate ENOMEM during read
13548         lctl set_param fail_loc=0x80000226
13549         cmp $TF $DIR/$tfile || error "cmp failed"
13550         lctl set_param fail_loc=0
13551
13552         rm -f $TF
13553 }
13554 run_test 152 "test read/write with enomem ============================"
13555
13556 test_153() {
13557         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13558 }
13559 run_test 153 "test if fdatasync does not crash ======================="
13560
13561 dot_lustre_fid_permission_check() {
13562         local fid=$1
13563         local ffid=$MOUNT/.lustre/fid/$fid
13564         local test_dir=$2
13565
13566         echo "stat fid $fid"
13567         stat $ffid > /dev/null || error "stat $ffid failed."
13568         echo "touch fid $fid"
13569         touch $ffid || error "touch $ffid failed."
13570         echo "write to fid $fid"
13571         cat /etc/hosts > $ffid || error "write $ffid failed."
13572         echo "read fid $fid"
13573         diff /etc/hosts $ffid || error "read $ffid failed."
13574         echo "append write to fid $fid"
13575         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13576         echo "rename fid $fid"
13577         mv $ffid $test_dir/$tfile.1 &&
13578                 error "rename $ffid to $tfile.1 should fail."
13579         touch $test_dir/$tfile.1
13580         mv $test_dir/$tfile.1 $ffid &&
13581                 error "rename $tfile.1 to $ffid should fail."
13582         rm -f $test_dir/$tfile.1
13583         echo "truncate fid $fid"
13584         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13585         echo "link fid $fid"
13586         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13587         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13588                 echo "setfacl fid $fid"
13589                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13590                 echo "getfacl fid $fid"
13591                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13592         fi
13593         echo "unlink fid $fid"
13594         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13595         echo "mknod fid $fid"
13596         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13597
13598         fid=[0xf00000400:0x1:0x0]
13599         ffid=$MOUNT/.lustre/fid/$fid
13600
13601         echo "stat non-exist fid $fid"
13602         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13603         echo "write to non-exist fid $fid"
13604         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13605         echo "link new fid $fid"
13606         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13607
13608         mkdir -p $test_dir/$tdir
13609         touch $test_dir/$tdir/$tfile
13610         fid=$($LFS path2fid $test_dir/$tdir)
13611         rc=$?
13612         [ $rc -ne 0 ] &&
13613                 error "error: could not get fid for $test_dir/$dir/$tfile."
13614
13615         ffid=$MOUNT/.lustre/fid/$fid
13616
13617         echo "ls $fid"
13618         ls $ffid > /dev/null || error "ls $ffid failed."
13619         echo "touch $fid/$tfile.1"
13620         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13621
13622         echo "touch $MOUNT/.lustre/fid/$tfile"
13623         touch $MOUNT/.lustre/fid/$tfile && \
13624                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13625
13626         echo "setxattr to $MOUNT/.lustre/fid"
13627         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13628
13629         echo "listxattr for $MOUNT/.lustre/fid"
13630         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13631
13632         echo "delxattr from $MOUNT/.lustre/fid"
13633         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13634
13635         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13636         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13637                 error "touch invalid fid should fail."
13638
13639         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13640         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13641                 error "touch non-normal fid should fail."
13642
13643         echo "rename $tdir to $MOUNT/.lustre/fid"
13644         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13645                 error "rename to $MOUNT/.lustre/fid should fail."
13646
13647         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13648         then            # LU-3547
13649                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13650                 local new_obf_mode=777
13651
13652                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13653                 chmod $new_obf_mode $DIR/.lustre/fid ||
13654                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13655
13656                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13657                 [ $obf_mode -eq $new_obf_mode ] ||
13658                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13659
13660                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13661                 chmod $old_obf_mode $DIR/.lustre/fid ||
13662                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13663         fi
13664
13665         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13666         fid=$($LFS path2fid $test_dir/$tfile-2)
13667
13668         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13669         then # LU-5424
13670                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13671                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13672                         error "create lov data thru .lustre failed"
13673         fi
13674         echo "cp /etc/passwd $test_dir/$tfile-2"
13675         cp /etc/passwd $test_dir/$tfile-2 ||
13676                 error "copy to $test_dir/$tfile-2 failed."
13677         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13678         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13679                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13680
13681         rm -rf $test_dir/tfile.lnk
13682         rm -rf $test_dir/$tfile-2
13683 }
13684
13685 test_154A() {
13686         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13687                 skip "Need MDS version at least 2.4.1"
13688
13689         local tf=$DIR/$tfile
13690         touch $tf
13691
13692         local fid=$($LFS path2fid $tf)
13693         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13694
13695         # check that we get the same pathname back
13696         local rootpath
13697         local found
13698         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
13699                 echo "$rootpath $fid"
13700                 found=$($LFS fid2path $rootpath "$fid")
13701                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13702                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
13703         done
13704
13705         # check wrong root path format
13706         rootpath=$MOUNT"_wrong"
13707         found=$($LFS fid2path $rootpath "$fid")
13708         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
13709 }
13710 run_test 154A "lfs path2fid and fid2path basic checks"
13711
13712 test_154B() {
13713         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13714                 skip "Need MDS version at least 2.4.1"
13715
13716         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13717         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13718         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13719         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13720
13721         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13722         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13723
13724         # check that we get the same pathname
13725         echo "PFID: $PFID, name: $name"
13726         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13727         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13728         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13729                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13730
13731         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13732 }
13733 run_test 154B "verify the ll_decode_linkea tool"
13734
13735 test_154a() {
13736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13737         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13738         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13739                 skip "Need MDS version at least 2.2.51"
13740         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13741
13742         cp /etc/hosts $DIR/$tfile
13743
13744         fid=$($LFS path2fid $DIR/$tfile)
13745         rc=$?
13746         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13747
13748         dot_lustre_fid_permission_check "$fid" $DIR ||
13749                 error "dot lustre permission check $fid failed"
13750
13751         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13752
13753         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13754
13755         touch $MOUNT/.lustre/file &&
13756                 error "creation is not allowed under .lustre"
13757
13758         mkdir $MOUNT/.lustre/dir &&
13759                 error "mkdir is not allowed under .lustre"
13760
13761         rm -rf $DIR/$tfile
13762 }
13763 run_test 154a "Open-by-FID"
13764
13765 test_154b() {
13766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13767         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13768         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13769         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13770                 skip "Need MDS version at least 2.2.51"
13771
13772         local remote_dir=$DIR/$tdir/remote_dir
13773         local MDTIDX=1
13774         local rc=0
13775
13776         mkdir -p $DIR/$tdir
13777         $LFS mkdir -i $MDTIDX $remote_dir ||
13778                 error "create remote directory failed"
13779
13780         cp /etc/hosts $remote_dir/$tfile
13781
13782         fid=$($LFS path2fid $remote_dir/$tfile)
13783         rc=$?
13784         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13785
13786         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13787                 error "dot lustre permission check $fid failed"
13788         rm -rf $DIR/$tdir
13789 }
13790 run_test 154b "Open-by-FID for remote directory"
13791
13792 test_154c() {
13793         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13794                 skip "Need MDS version at least 2.4.1"
13795
13796         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13797         local FID1=$($LFS path2fid $DIR/$tfile.1)
13798         local FID2=$($LFS path2fid $DIR/$tfile.2)
13799         local FID3=$($LFS path2fid $DIR/$tfile.3)
13800
13801         local N=1
13802         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13803                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13804                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13805                 local want=FID$N
13806                 [ "$FID" = "${!want}" ] ||
13807                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13808                 N=$((N + 1))
13809         done
13810
13811         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13812         do
13813                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13814                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13815                 N=$((N + 1))
13816         done
13817 }
13818 run_test 154c "lfs path2fid and fid2path multiple arguments"
13819
13820 test_154d() {
13821         remote_mds_nodsh && skip "remote MDS with nodsh"
13822         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13823                 skip "Need MDS version at least 2.5.53"
13824
13825         if remote_mds; then
13826                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13827         else
13828                 nid="0@lo"
13829         fi
13830         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13831         local fd
13832         local cmd
13833
13834         rm -f $DIR/$tfile
13835         touch $DIR/$tfile
13836
13837         local fid=$($LFS path2fid $DIR/$tfile)
13838         # Open the file
13839         fd=$(free_fd)
13840         cmd="exec $fd<$DIR/$tfile"
13841         eval $cmd
13842         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13843         echo "$fid_list" | grep "$fid"
13844         rc=$?
13845
13846         cmd="exec $fd>/dev/null"
13847         eval $cmd
13848         if [ $rc -ne 0 ]; then
13849                 error "FID $fid not found in open files list $fid_list"
13850         fi
13851 }
13852 run_test 154d "Verify open file fid"
13853
13854 test_154e()
13855 {
13856         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13857                 skip "Need MDS version at least 2.6.50"
13858
13859         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13860                 error ".lustre returned by readdir"
13861         fi
13862 }
13863 run_test 154e ".lustre is not returned by readdir"
13864
13865 test_154f() {
13866         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13867
13868         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13869         test_mkdir -p -c1 $DIR/$tdir/d
13870         # test dirs inherit from its stripe
13871         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13872         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13873         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13874         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13875         touch $DIR/f
13876
13877         # get fid of parents
13878         local FID0=$($LFS path2fid $DIR/$tdir/d)
13879         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13880         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13881         local FID3=$($LFS path2fid $DIR)
13882
13883         # check that path2fid --parents returns expected <parent_fid>/name
13884         # 1) test for a directory (single parent)
13885         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13886         [ "$parent" == "$FID0/foo1" ] ||
13887                 error "expected parent: $FID0/foo1, got: $parent"
13888
13889         # 2) test for a file with nlink > 1 (multiple parents)
13890         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13891         echo "$parent" | grep -F "$FID1/$tfile" ||
13892                 error "$FID1/$tfile not returned in parent list"
13893         echo "$parent" | grep -F "$FID2/link" ||
13894                 error "$FID2/link not returned in parent list"
13895
13896         # 3) get parent by fid
13897         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13898         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13899         echo "$parent" | grep -F "$FID1/$tfile" ||
13900                 error "$FID1/$tfile not returned in parent list (by fid)"
13901         echo "$parent" | grep -F "$FID2/link" ||
13902                 error "$FID2/link not returned in parent list (by fid)"
13903
13904         # 4) test for entry in root directory
13905         parent=$($LFS path2fid --parents $DIR/f)
13906         echo "$parent" | grep -F "$FID3/f" ||
13907                 error "$FID3/f not returned in parent list"
13908
13909         # 5) test it on root directory
13910         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13911                 error "$MOUNT should not have parents"
13912
13913         # enable xattr caching and check that linkea is correctly updated
13914         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13915         save_lustre_params client "llite.*.xattr_cache" > $save
13916         lctl set_param llite.*.xattr_cache 1
13917
13918         # 6.1) linkea update on rename
13919         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13920
13921         # get parents by fid
13922         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13923         # foo1 should no longer be returned in parent list
13924         echo "$parent" | grep -F "$FID1" &&
13925                 error "$FID1 should no longer be in parent list"
13926         # the new path should appear
13927         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13928                 error "$FID2/$tfile.moved is not in parent list"
13929
13930         # 6.2) linkea update on unlink
13931         rm -f $DIR/$tdir/d/foo2/link
13932         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13933         # foo2/link should no longer be returned in parent list
13934         echo "$parent" | grep -F "$FID2/link" &&
13935                 error "$FID2/link should no longer be in parent list"
13936         true
13937
13938         rm -f $DIR/f
13939         restore_lustre_params < $save
13940         rm -f $save
13941 }
13942 run_test 154f "get parent fids by reading link ea"
13943
13944 test_154g()
13945 {
13946         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13947         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
13948            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
13949                 skip "Need MDS version at least 2.6.92"
13950
13951         mkdir -p $DIR/$tdir
13952         llapi_fid_test -d $DIR/$tdir
13953 }
13954 run_test 154g "various llapi FID tests"
13955
13956 test_155_small_load() {
13957     local temp=$TMP/$tfile
13958     local file=$DIR/$tfile
13959
13960     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
13961         error "dd of=$temp bs=6096 count=1 failed"
13962     cp $temp $file
13963     cancel_lru_locks $OSC
13964     cmp $temp $file || error "$temp $file differ"
13965
13966     $TRUNCATE $temp 6000
13967     $TRUNCATE $file 6000
13968     cmp $temp $file || error "$temp $file differ (truncate1)"
13969
13970     echo "12345" >>$temp
13971     echo "12345" >>$file
13972     cmp $temp $file || error "$temp $file differ (append1)"
13973
13974     echo "12345" >>$temp
13975     echo "12345" >>$file
13976     cmp $temp $file || error "$temp $file differ (append2)"
13977
13978     rm -f $temp $file
13979     true
13980 }
13981
13982 test_155_big_load() {
13983         remote_ost_nodsh && skip "remote OST with nodsh"
13984
13985         local temp=$TMP/$tfile
13986         local file=$DIR/$tfile
13987
13988         free_min_max
13989         local cache_size=$(do_facet ost$((MAXI+1)) \
13990                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
13991         local large_file_size=$((cache_size * 2))
13992
13993         echo "OSS cache size: $cache_size KB"
13994         echo "Large file size: $large_file_size KB"
13995
13996         [ $MAXV -le $large_file_size ] &&
13997                 skip_env "max available OST size needs > $large_file_size KB"
13998
13999         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14000
14001         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14002                 error "dd of=$temp bs=$large_file_size count=1k failed"
14003         cp $temp $file
14004         ls -lh $temp $file
14005         cancel_lru_locks osc
14006         cmp $temp $file || error "$temp $file differ"
14007
14008         rm -f $temp $file
14009         true
14010 }
14011
14012 save_writethrough() {
14013         local facets=$(get_facets OST)
14014
14015         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14016 }
14017
14018 test_155a() {
14019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14020
14021         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14022
14023         save_writethrough $p
14024
14025         set_cache read on
14026         set_cache writethrough on
14027         test_155_small_load
14028         restore_lustre_params < $p
14029         rm -f $p
14030 }
14031 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14032
14033 test_155b() {
14034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14035
14036         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14037
14038         save_writethrough $p
14039
14040         set_cache read on
14041         set_cache writethrough off
14042         test_155_small_load
14043         restore_lustre_params < $p
14044         rm -f $p
14045 }
14046 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14047
14048 test_155c() {
14049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14050
14051         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14052
14053         save_writethrough $p
14054
14055         set_cache read off
14056         set_cache writethrough on
14057         test_155_small_load
14058         restore_lustre_params < $p
14059         rm -f $p
14060 }
14061 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14062
14063 test_155d() {
14064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14065
14066         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14067
14068         save_writethrough $p
14069
14070         set_cache read off
14071         set_cache writethrough off
14072         test_155_small_load
14073         restore_lustre_params < $p
14074         rm -f $p
14075 }
14076 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14077
14078 test_155e() {
14079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14080
14081         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14082
14083         save_writethrough $p
14084
14085         set_cache read on
14086         set_cache writethrough on
14087         test_155_big_load
14088         restore_lustre_params < $p
14089         rm -f $p
14090 }
14091 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14092
14093 test_155f() {
14094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14095
14096         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14097
14098         save_writethrough $p
14099
14100         set_cache read on
14101         set_cache writethrough off
14102         test_155_big_load
14103         restore_lustre_params < $p
14104         rm -f $p
14105 }
14106 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14107
14108 test_155g() {
14109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14110
14111         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14112
14113         save_writethrough $p
14114
14115         set_cache read off
14116         set_cache writethrough on
14117         test_155_big_load
14118         restore_lustre_params < $p
14119         rm -f $p
14120 }
14121 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14122
14123 test_155h() {
14124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14125
14126         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14127
14128         save_writethrough $p
14129
14130         set_cache read off
14131         set_cache writethrough off
14132         test_155_big_load
14133         restore_lustre_params < $p
14134         rm -f $p
14135 }
14136 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14137
14138 test_156() {
14139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14140         remote_ost_nodsh && skip "remote OST with nodsh"
14141         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14142                 skip "stats not implemented on old servers"
14143         [ "$ost1_FSTYPE" = "zfs" ] &&
14144                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14145
14146         local CPAGES=3
14147         local BEFORE
14148         local AFTER
14149         local file="$DIR/$tfile"
14150         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14151
14152         save_writethrough $p
14153         roc_hit_init
14154
14155         log "Turn on read and write cache"
14156         set_cache read on
14157         set_cache writethrough on
14158
14159         log "Write data and read it back."
14160         log "Read should be satisfied from the cache."
14161         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14162         BEFORE=$(roc_hit)
14163         cancel_lru_locks osc
14164         cat $file >/dev/null
14165         AFTER=$(roc_hit)
14166         if ! let "AFTER - BEFORE == CPAGES"; then
14167                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14168         else
14169                 log "cache hits: before: $BEFORE, after: $AFTER"
14170         fi
14171
14172         log "Read again; it should be satisfied from the cache."
14173         BEFORE=$AFTER
14174         cancel_lru_locks osc
14175         cat $file >/dev/null
14176         AFTER=$(roc_hit)
14177         if ! let "AFTER - BEFORE == CPAGES"; then
14178                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14179         else
14180                 log "cache hits:: before: $BEFORE, after: $AFTER"
14181         fi
14182
14183         log "Turn off the read cache and turn on the write cache"
14184         set_cache read off
14185         set_cache writethrough on
14186
14187         log "Read again; it should be satisfied from the cache."
14188         BEFORE=$(roc_hit)
14189         cancel_lru_locks osc
14190         cat $file >/dev/null
14191         AFTER=$(roc_hit)
14192         if ! let "AFTER - BEFORE == CPAGES"; then
14193                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14194         else
14195                 log "cache hits:: before: $BEFORE, after: $AFTER"
14196         fi
14197
14198         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14199                 # > 2.12.56 uses pagecache if cached
14200                 log "Read again; it should not be satisfied from the cache."
14201                 BEFORE=$AFTER
14202                 cancel_lru_locks osc
14203                 cat $file >/dev/null
14204                 AFTER=$(roc_hit)
14205                 if ! let "AFTER - BEFORE == 0"; then
14206                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14207                 else
14208                         log "cache hits:: before: $BEFORE, after: $AFTER"
14209                 fi
14210         fi
14211
14212         log "Write data and read it back."
14213         log "Read should be satisfied from the cache."
14214         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14215         BEFORE=$(roc_hit)
14216         cancel_lru_locks osc
14217         cat $file >/dev/null
14218         AFTER=$(roc_hit)
14219         if ! let "AFTER - BEFORE == CPAGES"; then
14220                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14221         else
14222                 log "cache hits:: before: $BEFORE, after: $AFTER"
14223         fi
14224
14225         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14226                 # > 2.12.56 uses pagecache if cached
14227                 log "Read again; it should not be satisfied from the cache."
14228                 BEFORE=$AFTER
14229                 cancel_lru_locks osc
14230                 cat $file >/dev/null
14231                 AFTER=$(roc_hit)
14232                 if ! let "AFTER - BEFORE == 0"; then
14233                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14234                 else
14235                         log "cache hits:: before: $BEFORE, after: $AFTER"
14236                 fi
14237         fi
14238
14239         log "Turn off read and write cache"
14240         set_cache read off
14241         set_cache writethrough off
14242
14243         log "Write data and read it back"
14244         log "It should not be satisfied from the cache."
14245         rm -f $file
14246         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14247         cancel_lru_locks osc
14248         BEFORE=$(roc_hit)
14249         cat $file >/dev/null
14250         AFTER=$(roc_hit)
14251         if ! let "AFTER - BEFORE == 0"; then
14252                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14253         else
14254                 log "cache hits:: before: $BEFORE, after: $AFTER"
14255         fi
14256
14257         log "Turn on the read cache and turn off the write cache"
14258         set_cache read on
14259         set_cache writethrough off
14260
14261         log "Write data and read it back"
14262         log "It should not be satisfied from the cache."
14263         rm -f $file
14264         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14265         BEFORE=$(roc_hit)
14266         cancel_lru_locks osc
14267         cat $file >/dev/null
14268         AFTER=$(roc_hit)
14269         if ! let "AFTER - BEFORE == 0"; then
14270                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14271         else
14272                 log "cache hits:: before: $BEFORE, after: $AFTER"
14273         fi
14274
14275         log "Read again; it should be satisfied from the cache."
14276         BEFORE=$(roc_hit)
14277         cancel_lru_locks osc
14278         cat $file >/dev/null
14279         AFTER=$(roc_hit)
14280         if ! let "AFTER - BEFORE == CPAGES"; then
14281                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14282         else
14283                 log "cache hits:: before: $BEFORE, after: $AFTER"
14284         fi
14285
14286         restore_lustre_params < $p
14287         rm -f $p $file
14288 }
14289 run_test 156 "Verification of tunables"
14290
14291 test_160a() {
14292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14293         remote_mds_nodsh && skip "remote MDS with nodsh"
14294         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14295                 skip "Need MDS version at least 2.2.0"
14296
14297         changelog_register || error "changelog_register failed"
14298         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14299         changelog_users $SINGLEMDS | grep -q $cl_user ||
14300                 error "User $cl_user not found in changelog_users"
14301
14302         # change something
14303         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14304         changelog_clear 0 || error "changelog_clear failed"
14305         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14306         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14307         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14308         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14309         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14310         rm $DIR/$tdir/pics/desktop.jpg
14311
14312         changelog_dump | tail -10
14313
14314         echo "verifying changelog mask"
14315         changelog_chmask "-MKDIR"
14316         changelog_chmask "-CLOSE"
14317
14318         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14319         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14320
14321         changelog_chmask "+MKDIR"
14322         changelog_chmask "+CLOSE"
14323
14324         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14325         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14326
14327         changelog_dump | tail -10
14328         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14329         CLOSES=$(changelog_dump | grep -c "CLOSE")
14330         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14331         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14332
14333         # verify contents
14334         echo "verifying target fid"
14335         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14336         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14337         [ "$fidc" == "$fidf" ] ||
14338                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14339         echo "verifying parent fid"
14340         # The FID returned from the Changelog may be the directory shard on
14341         # a different MDT, and not the FID returned by path2fid on the parent.
14342         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14343         # since this is what will matter when recreating this file in the tree.
14344         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14345         local pathp=$($LFS fid2path $MOUNT "$fidp")
14346         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14347                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14348
14349         echo "getting records for $cl_user"
14350         changelog_users $SINGLEMDS
14351         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14352         local nclr=3
14353         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14354                 error "changelog_clear failed"
14355         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14356         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14357         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14358                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14359
14360         local min0_rec=$(changelog_users $SINGLEMDS |
14361                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14362         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14363                           awk '{ print $1; exit; }')
14364
14365         changelog_dump | tail -n 5
14366         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14367         [ $first_rec == $((min0_rec + 1)) ] ||
14368                 error "first index should be $min0_rec + 1 not $first_rec"
14369
14370         # LU-3446 changelog index reset on MDT restart
14371         local cur_rec1=$(changelog_users $SINGLEMDS |
14372                          awk '/^current.index:/ { print $NF }')
14373         changelog_clear 0 ||
14374                 error "clear all changelog records for $cl_user failed"
14375         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14376         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14377                 error "Fail to start $SINGLEMDS"
14378         local cur_rec2=$(changelog_users $SINGLEMDS |
14379                          awk '/^current.index:/ { print $NF }')
14380         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14381         [ $cur_rec1 == $cur_rec2 ] ||
14382                 error "current index should be $cur_rec1 not $cur_rec2"
14383
14384         echo "verifying users from this test are deregistered"
14385         changelog_deregister || error "changelog_deregister failed"
14386         changelog_users $SINGLEMDS | grep -q $cl_user &&
14387                 error "User '$cl_user' still in changelog_users"
14388
14389         # lctl get_param -n mdd.*.changelog_users
14390         # current index: 144
14391         # ID    index (idle seconds)
14392         # cl3   144 (2)
14393         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14394                 # this is the normal case where all users were deregistered
14395                 # make sure no new records are added when no users are present
14396                 local last_rec1=$(changelog_users $SINGLEMDS |
14397                                   awk '/^current.index:/ { print $NF }')
14398                 touch $DIR/$tdir/chloe
14399                 local last_rec2=$(changelog_users $SINGLEMDS |
14400                                   awk '/^current.index:/ { print $NF }')
14401                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14402                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14403         else
14404                 # any changelog users must be leftovers from a previous test
14405                 changelog_users $SINGLEMDS
14406                 echo "other changelog users; can't verify off"
14407         fi
14408 }
14409 run_test 160a "changelog sanity"
14410
14411 test_160b() { # LU-3587
14412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14413         remote_mds_nodsh && skip "remote MDS with nodsh"
14414         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14415                 skip "Need MDS version at least 2.2.0"
14416
14417         changelog_register || error "changelog_register failed"
14418         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14419         changelog_users $SINGLEMDS | grep -q $cl_user ||
14420                 error "User '$cl_user' not found in changelog_users"
14421
14422         local longname1=$(str_repeat a 255)
14423         local longname2=$(str_repeat b 255)
14424
14425         cd $DIR
14426         echo "creating very long named file"
14427         touch $longname1 || error "create of '$longname1' failed"
14428         echo "renaming very long named file"
14429         mv $longname1 $longname2
14430
14431         changelog_dump | grep RENME | tail -n 5
14432         rm -f $longname2
14433 }
14434 run_test 160b "Verify that very long rename doesn't crash in changelog"
14435
14436 test_160c() {
14437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14438         remote_mds_nodsh && skip "remote MDS with nodsh"
14439
14440         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14441                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14442                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14443                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14444
14445         local rc=0
14446
14447         # Registration step
14448         changelog_register || error "changelog_register failed"
14449
14450         rm -rf $DIR/$tdir
14451         mkdir -p $DIR/$tdir
14452         $MCREATE $DIR/$tdir/foo_160c
14453         changelog_chmask "-TRUNC"
14454         $TRUNCATE $DIR/$tdir/foo_160c 200
14455         changelog_chmask "+TRUNC"
14456         $TRUNCATE $DIR/$tdir/foo_160c 199
14457         changelog_dump | tail -n 5
14458         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14459         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14460 }
14461 run_test 160c "verify that changelog log catch the truncate event"
14462
14463 test_160d() {
14464         remote_mds_nodsh && skip "remote MDS with nodsh"
14465         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14467         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14468                 skip "Need MDS version at least 2.7.60"
14469
14470         # Registration step
14471         changelog_register || error "changelog_register failed"
14472
14473         mkdir -p $DIR/$tdir/migrate_dir
14474         changelog_clear 0 || error "changelog_clear failed"
14475
14476         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14477         changelog_dump | tail -n 5
14478         local migrates=$(changelog_dump | grep -c "MIGRT")
14479         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14480 }
14481 run_test 160d "verify that changelog log catch the migrate event"
14482
14483 test_160e() {
14484         remote_mds_nodsh && skip "remote MDS with nodsh"
14485
14486         # Create a user
14487         changelog_register || error "changelog_register failed"
14488
14489         # Delete a future user (expect fail)
14490         local MDT0=$(facet_svc $SINGLEMDS)
14491         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14492         local rc=$?
14493
14494         if [ $rc -eq 0 ]; then
14495                 error "Deleted non-existant user cl77"
14496         elif [ $rc -ne 2 ]; then
14497                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14498         fi
14499
14500         # Clear to a bad index (1 billion should be safe)
14501         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14502         rc=$?
14503
14504         if [ $rc -eq 0 ]; then
14505                 error "Successfully cleared to invalid CL index"
14506         elif [ $rc -ne 22 ]; then
14507                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14508         fi
14509 }
14510 run_test 160e "changelog negative testing (should return errors)"
14511
14512 test_160f() {
14513         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14514         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14515                 skip "Need MDS version at least 2.10.56"
14516
14517         local mdts=$(comma_list $(mdts_nodes))
14518
14519         # Create a user
14520         changelog_register || error "first changelog_register failed"
14521         changelog_register || error "second changelog_register failed"
14522         local cl_users
14523         declare -A cl_user1
14524         declare -A cl_user2
14525         local user_rec1
14526         local user_rec2
14527         local i
14528
14529         # generate some changelog records to accumulate on each MDT
14530         # use fnv1a because created files should be evenly distributed
14531         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14532                 error "test_mkdir $tdir failed"
14533         log "$(date +%s): creating first files"
14534         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14535                 error "create $DIR/$tdir/$tfile failed"
14536
14537         # check changelogs have been generated
14538         local start=$SECONDS
14539         local idle_time=$((MDSCOUNT * 5 + 5))
14540         local nbcl=$(changelog_dump | wc -l)
14541         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14542
14543         for param in "changelog_max_idle_time=$idle_time" \
14544                      "changelog_gc=1" \
14545                      "changelog_min_gc_interval=2" \
14546                      "changelog_min_free_cat_entries=3"; do
14547                 local MDT0=$(facet_svc $SINGLEMDS)
14548                 local var="${param%=*}"
14549                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14550
14551                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14552                 do_nodes $mdts $LCTL set_param mdd.*.$param
14553         done
14554
14555         # force cl_user2 to be idle (1st part), but also cancel the
14556         # cl_user1 records so that it is not evicted later in the test.
14557         local sleep1=$((idle_time / 2))
14558         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14559         sleep $sleep1
14560
14561         # simulate changelog catalog almost full
14562         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14563         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14564
14565         for i in $(seq $MDSCOUNT); do
14566                 cl_users=(${CL_USERS[mds$i]})
14567                 cl_user1[mds$i]="${cl_users[0]}"
14568                 cl_user2[mds$i]="${cl_users[1]}"
14569
14570                 [ -n "${cl_user1[mds$i]}" ] ||
14571                         error "mds$i: no user registered"
14572                 [ -n "${cl_user2[mds$i]}" ] ||
14573                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14574
14575                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14576                 [ -n "$user_rec1" ] ||
14577                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14578                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14579                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14580                 [ -n "$user_rec2" ] ||
14581                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14582                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14583                      "$user_rec1 + 2 == $user_rec2"
14584                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14585                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14586                               "$user_rec1 + 2, but is $user_rec2"
14587                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14588                 [ -n "$user_rec2" ] ||
14589                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14590                 [ $user_rec1 == $user_rec2 ] ||
14591                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14592                               "$user_rec1, but is $user_rec2"
14593         done
14594
14595         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14596         local sleep2=$((idle_time - (SECONDS - start) + 1))
14597         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14598         sleep $sleep2
14599
14600         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14601         # cl_user1 should be OK because it recently processed records.
14602         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14603         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14604                 error "create $DIR/$tdir/${tfile}b failed"
14605
14606         # ensure gc thread is done
14607         for i in $(mdts_nodes); do
14608                 wait_update $i \
14609                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14610                         error "$i: GC-thread not done"
14611         done
14612
14613         local first_rec
14614         for i in $(seq $MDSCOUNT); do
14615                 # check cl_user1 still registered
14616                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14617                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14618                 # check cl_user2 unregistered
14619                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14620                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14621
14622                 # check changelogs are present and starting at $user_rec1 + 1
14623                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14624                 [ -n "$user_rec1" ] ||
14625                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14626                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14627                             awk '{ print $1; exit; }')
14628
14629                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14630                 [ $((user_rec1 + 1)) == $first_rec ] ||
14631                         error "mds$i: first index should be $user_rec1 + 1, " \
14632                               "but is $first_rec"
14633         done
14634 }
14635 run_test 160f "changelog garbage collect (timestamped users)"
14636
14637 test_160g() {
14638         remote_mds_nodsh && skip "remote MDS with nodsh"
14639         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14640                 skip "Need MDS version at least 2.10.56"
14641
14642         local mdts=$(comma_list $(mdts_nodes))
14643
14644         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14645         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14646
14647         # Create a user
14648         changelog_register || error "first changelog_register failed"
14649         changelog_register || error "second changelog_register failed"
14650         local cl_users
14651         declare -A cl_user1
14652         declare -A cl_user2
14653         local user_rec1
14654         local user_rec2
14655         local i
14656
14657         # generate some changelog records to accumulate on each MDT
14658         # use fnv1a because created files should be evenly distributed
14659         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14660                 error "mkdir $tdir failed"
14661         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14662                 error "create $DIR/$tdir/$tfile failed"
14663
14664         # check changelogs have been generated
14665         local nbcl=$(changelog_dump | wc -l)
14666         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14667
14668         # reduce the max_idle_indexes value to make sure we exceed it
14669         max_ndx=$((nbcl / 2 - 1))
14670
14671         for param in "changelog_max_idle_indexes=$max_ndx" \
14672                      "changelog_gc=1" \
14673                      "changelog_min_gc_interval=2" \
14674                      "changelog_min_free_cat_entries=3"; do
14675                 local MDT0=$(facet_svc $SINGLEMDS)
14676                 local var="${param%=*}"
14677                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14678
14679                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14680                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14681                         error "unable to set mdd.*.$param"
14682         done
14683
14684         # simulate changelog catalog almost full
14685         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14686         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14687
14688         for i in $(seq $MDSCOUNT); do
14689                 cl_users=(${CL_USERS[mds$i]})
14690                 cl_user1[mds$i]="${cl_users[0]}"
14691                 cl_user2[mds$i]="${cl_users[1]}"
14692
14693                 [ -n "${cl_user1[mds$i]}" ] ||
14694                         error "mds$i: no user registered"
14695                 [ -n "${cl_user2[mds$i]}" ] ||
14696                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14697
14698                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14699                 [ -n "$user_rec1" ] ||
14700                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14701                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14702                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14703                 [ -n "$user_rec2" ] ||
14704                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14705                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14706                      "$user_rec1 + 2 == $user_rec2"
14707                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14708                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14709                               "$user_rec1 + 2, but is $user_rec2"
14710                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14711                 [ -n "$user_rec2" ] ||
14712                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14713                 [ $user_rec1 == $user_rec2 ] ||
14714                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14715                               "$user_rec1, but is $user_rec2"
14716         done
14717
14718         # ensure we are past the previous changelog_min_gc_interval set above
14719         sleep 2
14720
14721         # generate one more changelog to trigger fail_loc
14722         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14723                 error "create $DIR/$tdir/${tfile}bis failed"
14724
14725         # ensure gc thread is done
14726         for i in $(mdts_nodes); do
14727                 wait_update $i \
14728                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14729                         error "$i: GC-thread not done"
14730         done
14731
14732         local first_rec
14733         for i in $(seq $MDSCOUNT); do
14734                 # check cl_user1 still registered
14735                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14736                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14737                 # check cl_user2 unregistered
14738                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14739                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14740
14741                 # check changelogs are present and starting at $user_rec1 + 1
14742                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14743                 [ -n "$user_rec1" ] ||
14744                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14745                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14746                             awk '{ print $1; exit; }')
14747
14748                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14749                 [ $((user_rec1 + 1)) == $first_rec ] ||
14750                         error "mds$i: first index should be $user_rec1 + 1, " \
14751                               "but is $first_rec"
14752         done
14753 }
14754 run_test 160g "changelog garbage collect (old users)"
14755
14756 test_160h() {
14757         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14758         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14759                 skip "Need MDS version at least 2.10.56"
14760
14761         local mdts=$(comma_list $(mdts_nodes))
14762
14763         # Create a user
14764         changelog_register || error "first changelog_register failed"
14765         changelog_register || error "second changelog_register failed"
14766         local cl_users
14767         declare -A cl_user1
14768         declare -A cl_user2
14769         local user_rec1
14770         local user_rec2
14771         local i
14772
14773         # generate some changelog records to accumulate on each MDT
14774         # use fnv1a because created files should be evenly distributed
14775         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14776                 error "test_mkdir $tdir failed"
14777         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14778                 error "create $DIR/$tdir/$tfile failed"
14779
14780         # check changelogs have been generated
14781         local nbcl=$(changelog_dump | wc -l)
14782         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14783
14784         for param in "changelog_max_idle_time=10" \
14785                      "changelog_gc=1" \
14786                      "changelog_min_gc_interval=2"; do
14787                 local MDT0=$(facet_svc $SINGLEMDS)
14788                 local var="${param%=*}"
14789                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14790
14791                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14792                 do_nodes $mdts $LCTL set_param mdd.*.$param
14793         done
14794
14795         # force cl_user2 to be idle (1st part)
14796         sleep 9
14797
14798         for i in $(seq $MDSCOUNT); do
14799                 cl_users=(${CL_USERS[mds$i]})
14800                 cl_user1[mds$i]="${cl_users[0]}"
14801                 cl_user2[mds$i]="${cl_users[1]}"
14802
14803                 [ -n "${cl_user1[mds$i]}" ] ||
14804                         error "mds$i: no user registered"
14805                 [ -n "${cl_user2[mds$i]}" ] ||
14806                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14807
14808                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14809                 [ -n "$user_rec1" ] ||
14810                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14811                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14812                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14813                 [ -n "$user_rec2" ] ||
14814                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14815                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14816                      "$user_rec1 + 2 == $user_rec2"
14817                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14818                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14819                               "$user_rec1 + 2, but is $user_rec2"
14820                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14821                 [ -n "$user_rec2" ] ||
14822                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14823                 [ $user_rec1 == $user_rec2 ] ||
14824                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14825                               "$user_rec1, but is $user_rec2"
14826         done
14827
14828         # force cl_user2 to be idle (2nd part) and to reach
14829         # changelog_max_idle_time
14830         sleep 2
14831
14832         # force each GC-thread start and block then
14833         # one per MDT/MDD, set fail_val accordingly
14834         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14835         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14836
14837         # generate more changelogs to trigger fail_loc
14838         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14839                 error "create $DIR/$tdir/${tfile}bis failed"
14840
14841         # stop MDT to stop GC-thread, should be done in back-ground as it will
14842         # block waiting for the thread to be released and exit
14843         declare -A stop_pids
14844         for i in $(seq $MDSCOUNT); do
14845                 stop mds$i &
14846                 stop_pids[mds$i]=$!
14847         done
14848
14849         for i in $(mdts_nodes); do
14850                 local facet
14851                 local nb=0
14852                 local facets=$(facets_up_on_host $i)
14853
14854                 for facet in ${facets//,/ }; do
14855                         if [[ $facet == mds* ]]; then
14856                                 nb=$((nb + 1))
14857                         fi
14858                 done
14859                 # ensure each MDS's gc threads are still present and all in "R"
14860                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14861                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14862                         error "$i: expected $nb GC-thread"
14863                 wait_update $i \
14864                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14865                         "R" 20 ||
14866                         error "$i: GC-thread not found in R-state"
14867                 # check umounts of each MDT on MDS have reached kthread_stop()
14868                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14869                         error "$i: expected $nb umount"
14870                 wait_update $i \
14871                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14872                         error "$i: umount not found in D-state"
14873         done
14874
14875         # release all GC-threads
14876         do_nodes $mdts $LCTL set_param fail_loc=0
14877
14878         # wait for MDT stop to complete
14879         for i in $(seq $MDSCOUNT); do
14880                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14881         done
14882
14883         # XXX
14884         # may try to check if any orphan changelog records are present
14885         # via ldiskfs/zfs and llog_reader...
14886
14887         # re-start/mount MDTs
14888         for i in $(seq $MDSCOUNT); do
14889                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14890                         error "Fail to start mds$i"
14891         done
14892
14893         local first_rec
14894         for i in $(seq $MDSCOUNT); do
14895                 # check cl_user1 still registered
14896                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14897                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14898                 # check cl_user2 unregistered
14899                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14900                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14901
14902                 # check changelogs are present and starting at $user_rec1 + 1
14903                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14904                 [ -n "$user_rec1" ] ||
14905                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14906                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14907                             awk '{ print $1; exit; }')
14908
14909                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14910                 [ $((user_rec1 + 1)) == $first_rec ] ||
14911                         error "mds$i: first index should be $user_rec1 + 1, " \
14912                               "but is $first_rec"
14913         done
14914 }
14915 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14916               "during mount"
14917
14918 test_160i() {
14919
14920         local mdts=$(comma_list $(mdts_nodes))
14921
14922         changelog_register || error "first changelog_register failed"
14923
14924         # generate some changelog records to accumulate on each MDT
14925         # use fnv1a because created files should be evenly distributed
14926         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14927                 error "mkdir $tdir failed"
14928         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14929                 error "create $DIR/$tdir/$tfile failed"
14930
14931         # check changelogs have been generated
14932         local nbcl=$(changelog_dump | wc -l)
14933         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14934
14935         # simulate race between register and unregister
14936         # XXX as fail_loc is set per-MDS, with DNE configs the race
14937         # simulation will only occur for one MDT per MDS and for the
14938         # others the normal race scenario will take place
14939         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
14940         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
14941         do_nodes $mdts $LCTL set_param fail_val=1
14942
14943         # unregister 1st user
14944         changelog_deregister &
14945         local pid1=$!
14946         # wait some time for deregister work to reach race rdv
14947         sleep 2
14948         # register 2nd user
14949         changelog_register || error "2nd user register failed"
14950
14951         wait $pid1 || error "1st user deregister failed"
14952
14953         local i
14954         local last_rec
14955         declare -A LAST_REC
14956         for i in $(seq $MDSCOUNT); do
14957                 if changelog_users mds$i | grep "^cl"; then
14958                         # make sure new records are added with one user present
14959                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
14960                                           awk '/^current.index:/ { print $NF }')
14961                 else
14962                         error "mds$i has no user registered"
14963                 fi
14964         done
14965
14966         # generate more changelog records to accumulate on each MDT
14967         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14968                 error "create $DIR/$tdir/${tfile}bis failed"
14969
14970         for i in $(seq $MDSCOUNT); do
14971                 last_rec=$(changelog_users $SINGLEMDS |
14972                            awk '/^current.index:/ { print $NF }')
14973                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
14974                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
14975                         error "changelogs are off on mds$i"
14976         done
14977 }
14978 run_test 160i "changelog user register/unregister race"
14979
14980 test_160j() {
14981         remote_mds_nodsh && skip "remote MDS with nodsh"
14982         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
14983                 skip "Need MDS version at least 2.12.56"
14984
14985         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
14986         stack_trap "umount $MOUNT2" EXIT
14987
14988         changelog_register || error "first changelog_register failed"
14989         stack_trap "changelog_deregister" EXIT
14990
14991         # generate some changelog
14992         # use fnv1a because created files should be evenly distributed
14993         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14994                 error "mkdir $tdir failed"
14995         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14996                 error "create $DIR/$tdir/${tfile}bis failed"
14997
14998         # open the changelog device
14999         exec 3>/dev/changelog-$FSNAME-MDT0000
15000         stack_trap "exec 3>&-" EXIT
15001         exec 4</dev/changelog-$FSNAME-MDT0000
15002         stack_trap "exec 4<&-" EXIT
15003
15004         # umount the first lustre mount
15005         umount $MOUNT
15006         stack_trap "mount_client $MOUNT" EXIT
15007
15008         # read changelog
15009         cat <&4 >/dev/null || error "read changelog failed"
15010
15011         # clear changelog
15012         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15013         changelog_users $SINGLEMDS | grep -q $cl_user ||
15014                 error "User $cl_user not found in changelog_users"
15015
15016         printf 'clear:'$cl_user':0' >&3
15017 }
15018 run_test 160j "client can be umounted  while its chanangelog is being used"
15019
15020 test_160k() {
15021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15022         remote_mds_nodsh && skip "remote MDS with nodsh"
15023
15024         mkdir -p $DIR/$tdir/1/1
15025
15026         changelog_register || error "changelog_register failed"
15027         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15028
15029         changelog_users $SINGLEMDS | grep -q $cl_user ||
15030                 error "User '$cl_user' not found in changelog_users"
15031 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15032         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15033         rmdir $DIR/$tdir/1/1 & sleep 1
15034         mkdir $DIR/$tdir/2
15035         touch $DIR/$tdir/2/2
15036         rm -rf $DIR/$tdir/2
15037
15038         wait
15039         sleep 4
15040
15041         changelog_dump | grep rmdir || error "rmdir not recorded"
15042
15043         rm -rf $DIR/$tdir
15044         changelog_deregister
15045 }
15046 run_test 160k "Verify that changelog records are not lost"
15047
15048 # Verifies that a file passed as a parameter has recently had an operation
15049 # performed on it that has generated an MTIME changelog which contains the
15050 # correct parent FID. As files might reside on a different MDT from the
15051 # parent directory in DNE configurations, the FIDs are translated to paths
15052 # before being compared, which should be identical
15053 compare_mtime_changelog() {
15054         local file="${1}"
15055         local mdtidx
15056         local mtime
15057         local cl_fid
15058         local pdir
15059         local dir
15060
15061         mdtidx=$($LFS getstripe --mdt-index $file)
15062         mdtidx=$(printf "%04x" $mdtidx)
15063
15064         # Obtain the parent FID from the MTIME changelog
15065         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15066         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15067
15068         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15069         [ -z "$cl_fid" ] && error "parent FID not present"
15070
15071         # Verify that the path for the parent FID is the same as the path for
15072         # the test directory
15073         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15074
15075         dir=$(dirname $1)
15076
15077         [[ "${pdir%/}" == "$dir" ]] ||
15078                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15079 }
15080
15081 test_160l() {
15082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15083
15084         remote_mds_nodsh && skip "remote MDS with nodsh"
15085         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15086                 skip "Need MDS version at least 2.13.55"
15087
15088         local cl_user
15089
15090         changelog_register || error "changelog_register failed"
15091         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15092
15093         changelog_users $SINGLEMDS | grep -q $cl_user ||
15094                 error "User '$cl_user' not found in changelog_users"
15095
15096         # Clear some types so that MTIME changelogs are generated
15097         changelog_chmask "-CREAT"
15098         changelog_chmask "-CLOSE"
15099
15100         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15101
15102         # Test CL_MTIME during setattr
15103         touch $DIR/$tdir/$tfile
15104         compare_mtime_changelog $DIR/$tdir/$tfile
15105
15106         # Test CL_MTIME during close
15107         dd if=/dev/urandom of=$DIR/$tdir/${tfile}_2 bs=1M count=64 ||
15108                 error "cannot create file $DIR/$tdir/${tfile}_2"
15109         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15110 }
15111 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15112
15113 test_161a() {
15114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15115
15116         test_mkdir -c1 $DIR/$tdir
15117         cp /etc/hosts $DIR/$tdir/$tfile
15118         test_mkdir -c1 $DIR/$tdir/foo1
15119         test_mkdir -c1 $DIR/$tdir/foo2
15120         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15121         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15122         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15123         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15124         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15125         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15126                 $LFS fid2path $DIR $FID
15127                 error "bad link ea"
15128         fi
15129         # middle
15130         rm $DIR/$tdir/foo2/zachary
15131         # last
15132         rm $DIR/$tdir/foo2/thor
15133         # first
15134         rm $DIR/$tdir/$tfile
15135         # rename
15136         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15137         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15138                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15139         rm $DIR/$tdir/foo2/maggie
15140
15141         # overflow the EA
15142         local longname=$tfile.avg_len_is_thirty_two_
15143         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15144                 error_noexit 'failed to unlink many hardlinks'" EXIT
15145         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15146                 error "failed to hardlink many files"
15147         links=$($LFS fid2path $DIR $FID | wc -l)
15148         echo -n "${links}/1000 links in link EA"
15149         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15150 }
15151 run_test 161a "link ea sanity"
15152
15153 test_161b() {
15154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15155         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15156
15157         local MDTIDX=1
15158         local remote_dir=$DIR/$tdir/remote_dir
15159
15160         mkdir -p $DIR/$tdir
15161         $LFS mkdir -i $MDTIDX $remote_dir ||
15162                 error "create remote directory failed"
15163
15164         cp /etc/hosts $remote_dir/$tfile
15165         mkdir -p $remote_dir/foo1
15166         mkdir -p $remote_dir/foo2
15167         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15168         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15169         ln $remote_dir/$tfile $remote_dir/foo1/luna
15170         ln $remote_dir/$tfile $remote_dir/foo2/thor
15171
15172         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15173                      tr -d ']')
15174         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15175                 $LFS fid2path $DIR $FID
15176                 error "bad link ea"
15177         fi
15178         # middle
15179         rm $remote_dir/foo2/zachary
15180         # last
15181         rm $remote_dir/foo2/thor
15182         # first
15183         rm $remote_dir/$tfile
15184         # rename
15185         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15186         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15187         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15188                 $LFS fid2path $DIR $FID
15189                 error "bad link rename"
15190         fi
15191         rm $remote_dir/foo2/maggie
15192
15193         # overflow the EA
15194         local longname=filename_avg_len_is_thirty_two_
15195         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15196                 error "failed to hardlink many files"
15197         links=$($LFS fid2path $DIR $FID | wc -l)
15198         echo -n "${links}/1000 links in link EA"
15199         [[ ${links} -gt 60 ]] ||
15200                 error "expected at least 60 links in link EA"
15201         unlinkmany $remote_dir/foo2/$longname 1000 ||
15202         error "failed to unlink many hardlinks"
15203 }
15204 run_test 161b "link ea sanity under remote directory"
15205
15206 test_161c() {
15207         remote_mds_nodsh && skip "remote MDS with nodsh"
15208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15209         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15210                 skip "Need MDS version at least 2.1.5"
15211
15212         # define CLF_RENAME_LAST 0x0001
15213         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15214         changelog_register || error "changelog_register failed"
15215
15216         rm -rf $DIR/$tdir
15217         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15218         touch $DIR/$tdir/foo_161c
15219         touch $DIR/$tdir/bar_161c
15220         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15221         changelog_dump | grep RENME | tail -n 5
15222         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15223         changelog_clear 0 || error "changelog_clear failed"
15224         if [ x$flags != "x0x1" ]; then
15225                 error "flag $flags is not 0x1"
15226         fi
15227
15228         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15229         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15230         touch $DIR/$tdir/foo_161c
15231         touch $DIR/$tdir/bar_161c
15232         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15233         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15234         changelog_dump | grep RENME | tail -n 5
15235         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15236         changelog_clear 0 || error "changelog_clear failed"
15237         if [ x$flags != "x0x0" ]; then
15238                 error "flag $flags is not 0x0"
15239         fi
15240         echo "rename overwrite a target having nlink > 1," \
15241                 "changelog record has flags of $flags"
15242
15243         # rename doesn't overwrite a target (changelog flag 0x0)
15244         touch $DIR/$tdir/foo_161c
15245         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15246         changelog_dump | grep RENME | tail -n 5
15247         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15248         changelog_clear 0 || error "changelog_clear failed"
15249         if [ x$flags != "x0x0" ]; then
15250                 error "flag $flags is not 0x0"
15251         fi
15252         echo "rename doesn't overwrite a target," \
15253                 "changelog record has flags of $flags"
15254
15255         # define CLF_UNLINK_LAST 0x0001
15256         # unlink a file having nlink = 1 (changelog flag 0x1)
15257         rm -f $DIR/$tdir/foo2_161c
15258         changelog_dump | grep UNLNK | tail -n 5
15259         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15260         changelog_clear 0 || error "changelog_clear failed"
15261         if [ x$flags != "x0x1" ]; then
15262                 error "flag $flags is not 0x1"
15263         fi
15264         echo "unlink a file having nlink = 1," \
15265                 "changelog record has flags of $flags"
15266
15267         # unlink a file having nlink > 1 (changelog flag 0x0)
15268         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15269         rm -f $DIR/$tdir/foobar_161c
15270         changelog_dump | grep UNLNK | tail -n 5
15271         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15272         changelog_clear 0 || error "changelog_clear failed"
15273         if [ x$flags != "x0x0" ]; then
15274                 error "flag $flags is not 0x0"
15275         fi
15276         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15277 }
15278 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15279
15280 test_161d() {
15281         remote_mds_nodsh && skip "remote MDS with nodsh"
15282         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15283
15284         local pid
15285         local fid
15286
15287         changelog_register || error "changelog_register failed"
15288
15289         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15290         # interfer with $MOUNT/.lustre/fid/ access
15291         mkdir $DIR/$tdir
15292         [[ $? -eq 0 ]] || error "mkdir failed"
15293
15294         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15295         $LCTL set_param fail_loc=0x8000140c
15296         # 5s pause
15297         $LCTL set_param fail_val=5
15298
15299         # create file
15300         echo foofoo > $DIR/$tdir/$tfile &
15301         pid=$!
15302
15303         # wait for create to be delayed
15304         sleep 2
15305
15306         ps -p $pid
15307         [[ $? -eq 0 ]] || error "create should be blocked"
15308
15309         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15310         stack_trap "rm -f $tempfile"
15311         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15312         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15313         # some delay may occur during ChangeLog publishing and file read just
15314         # above, that could allow file write to happen finally
15315         [[ -s $tempfile ]] && echo "file should be empty"
15316
15317         $LCTL set_param fail_loc=0
15318
15319         wait $pid
15320         [[ $? -eq 0 ]] || error "create failed"
15321 }
15322 run_test 161d "create with concurrent .lustre/fid access"
15323
15324 check_path() {
15325         local expected="$1"
15326         shift
15327         local fid="$2"
15328
15329         local path
15330         path=$($LFS fid2path "$@")
15331         local rc=$?
15332
15333         if [ $rc -ne 0 ]; then
15334                 error "path looked up of '$expected' failed: rc=$rc"
15335         elif [ "$path" != "$expected" ]; then
15336                 error "path looked up '$path' instead of '$expected'"
15337         else
15338                 echo "FID '$fid' resolves to path '$path' as expected"
15339         fi
15340 }
15341
15342 test_162a() { # was test_162
15343         test_mkdir -p -c1 $DIR/$tdir/d2
15344         touch $DIR/$tdir/d2/$tfile
15345         touch $DIR/$tdir/d2/x1
15346         touch $DIR/$tdir/d2/x2
15347         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15348         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15349         # regular file
15350         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15351         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15352
15353         # softlink
15354         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15355         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15356         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15357
15358         # softlink to wrong file
15359         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15360         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15361         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15362
15363         # hardlink
15364         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15365         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15366         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15367         # fid2path dir/fsname should both work
15368         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15369         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15370
15371         # hardlink count: check that there are 2 links
15372         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15373         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15374
15375         # hardlink indexing: remove the first link
15376         rm $DIR/$tdir/d2/p/q/r/hlink
15377         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15378 }
15379 run_test 162a "path lookup sanity"
15380
15381 test_162b() {
15382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15383         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15384
15385         mkdir $DIR/$tdir
15386         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15387                                 error "create striped dir failed"
15388
15389         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15390                                         tail -n 1 | awk '{print $2}')
15391         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15392
15393         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15394         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15395
15396         # regular file
15397         for ((i=0;i<5;i++)); do
15398                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15399                         error "get fid for f$i failed"
15400                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15401
15402                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15403                         error "get fid for d$i failed"
15404                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15405         done
15406
15407         return 0
15408 }
15409 run_test 162b "striped directory path lookup sanity"
15410
15411 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15412 test_162c() {
15413         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15414                 skip "Need MDS version at least 2.7.51"
15415
15416         local lpath=$tdir.local
15417         local rpath=$tdir.remote
15418
15419         test_mkdir $DIR/$lpath
15420         test_mkdir $DIR/$rpath
15421
15422         for ((i = 0; i <= 101; i++)); do
15423                 lpath="$lpath/$i"
15424                 mkdir $DIR/$lpath
15425                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15426                         error "get fid for local directory $DIR/$lpath failed"
15427                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15428
15429                 rpath="$rpath/$i"
15430                 test_mkdir $DIR/$rpath
15431                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15432                         error "get fid for remote directory $DIR/$rpath failed"
15433                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15434         done
15435
15436         return 0
15437 }
15438 run_test 162c "fid2path works with paths 100 or more directories deep"
15439
15440 oalr_event_count() {
15441         local event="${1}"
15442         local trace="${2}"
15443
15444         awk -v name="${FSNAME}-OST0000" \
15445             -v event="${event}" \
15446             '$1 == "TRACE" && $2 == event && $3 == name' \
15447             "${trace}" |
15448         wc -l
15449 }
15450
15451 oalr_expect_event_count() {
15452         local event="${1}"
15453         local trace="${2}"
15454         local expect="${3}"
15455         local count
15456
15457         count=$(oalr_event_count "${event}" "${trace}")
15458         if ((count == expect)); then
15459                 return 0
15460         fi
15461
15462         error_noexit "${event} event count was '${count}', expected ${expect}"
15463         cat "${trace}" >&2
15464         exit 1
15465 }
15466
15467 cleanup_165() {
15468         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15469         stop ost1
15470         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15471 }
15472
15473 setup_165() {
15474         sync # Flush previous IOs so we can count log entries.
15475         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15476         stack_trap cleanup_165 EXIT
15477 }
15478
15479 test_165a() {
15480         local trace="/tmp/${tfile}.trace"
15481         local rc
15482         local count
15483
15484         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15485         setup_165
15486         sleep 5
15487
15488         do_facet ost1 ofd_access_log_reader --list
15489         stop ost1
15490
15491         do_facet ost1 killall -TERM ofd_access_log_reader
15492         wait
15493         rc=$?
15494
15495         if ((rc != 0)); then
15496                 error "ofd_access_log_reader exited with rc = '${rc}'"
15497         fi
15498
15499         # Parse trace file for discovery events:
15500         oalr_expect_event_count alr_log_add "${trace}" 1
15501         oalr_expect_event_count alr_log_eof "${trace}" 1
15502         oalr_expect_event_count alr_log_free "${trace}" 1
15503 }
15504 run_test 165a "ofd access log discovery"
15505
15506 test_165b() {
15507         local trace="/tmp/${tfile}.trace"
15508         local file="${DIR}/${tfile}"
15509         local pfid1
15510         local pfid2
15511         local -a entry
15512         local rc
15513         local count
15514         local size
15515         local flags
15516
15517         setup_165
15518
15519         lfs setstripe -c 1 -i 0 "${file}"
15520         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15521         do_facet ost1 ofd_access_log_reader --list
15522
15523         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15524         sleep 5
15525         do_facet ost1 killall -TERM ofd_access_log_reader
15526         wait
15527         rc=$?
15528
15529         if ((rc != 0)); then
15530                 error "ofd_access_log_reader exited with rc = '${rc}'"
15531         fi
15532
15533         oalr_expect_event_count alr_log_entry "${trace}" 1
15534
15535         pfid1=$($LFS path2fid "${file}")
15536
15537         # 1     2             3   4    5     6   7    8    9     10
15538         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15539         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15540
15541         echo "entry = '${entry[*]}'" >&2
15542
15543         pfid2=${entry[4]}
15544         if [[ "${pfid1}" != "${pfid2}" ]]; then
15545                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15546         fi
15547
15548         size=${entry[8]}
15549         if ((size != 1048576)); then
15550                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15551         fi
15552
15553         flags=${entry[10]}
15554         if [[ "${flags}" != "w" ]]; then
15555                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15556         fi
15557
15558         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15559         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c || error "cannot read '${file}'"
15560         sleep 5
15561         do_facet ost1 killall -TERM ofd_access_log_reader
15562         wait
15563         rc=$?
15564
15565         if ((rc != 0)); then
15566                 error "ofd_access_log_reader exited with rc = '${rc}'"
15567         fi
15568
15569         oalr_expect_event_count alr_log_entry "${trace}" 1
15570
15571         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15572         echo "entry = '${entry[*]}'" >&2
15573
15574         pfid2=${entry[4]}
15575         if [[ "${pfid1}" != "${pfid2}" ]]; then
15576                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15577         fi
15578
15579         size=${entry[8]}
15580         if ((size != 524288)); then
15581                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15582         fi
15583
15584         flags=${entry[10]}
15585         if [[ "${flags}" != "r" ]]; then
15586                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15587         fi
15588 }
15589 run_test 165b "ofd access log entries are produced and consumed"
15590
15591 test_165c() {
15592         local file="${DIR}/${tdir}/${tfile}"
15593         test_mkdir "${DIR}/${tdir}"
15594
15595         setup_165
15596
15597         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
15598
15599         # 4096 / 64 = 64. Create twice as many entries.
15600         for ((i = 0; i < 128; i++)); do
15601                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c || error "cannot create file"
15602         done
15603
15604         sync
15605         do_facet ost1 ofd_access_log_reader --list
15606         unlinkmany  "${file}-%d" 128
15607 }
15608 run_test 165c "full ofd access logs do not block IOs"
15609
15610 oal_peek_entry_count() {
15611         do_facet ost1 ofd_access_log_reader --list | awk '$1 == "_entry_count:" { print $2; }'
15612 }
15613
15614 oal_expect_entry_count() {
15615         local entry_count=$(oal_peek_entry_count)
15616         local expect="$1"
15617
15618         if ((entry_count == expect)); then
15619                 return 0
15620         fi
15621
15622         error_noexit "bad entry count, got ${entry_count}, expected ${expect}"
15623         do_facet ost1 ofd_access_log_reader --list >&2
15624         exit 1
15625 }
15626
15627 test_165d() {
15628         local trace="/tmp/${tfile}.trace"
15629         local file="${DIR}/${tdir}/${tfile}"
15630         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
15631         local entry_count
15632         test_mkdir "${DIR}/${tdir}"
15633
15634         setup_165
15635         lfs setstripe -c 1 -i 0 "${file}"
15636
15637         do_facet ost1 lctl set_param "${param}=rw"
15638         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15639         oal_expect_entry_count 1
15640
15641         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15642         oal_expect_entry_count 2
15643
15644         do_facet ost1 lctl set_param "${param}=r"
15645         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15646         oal_expect_entry_count 2
15647
15648         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15649         oal_expect_entry_count 3
15650
15651         do_facet ost1 lctl set_param "${param}=w"
15652         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15653         oal_expect_entry_count 4
15654
15655         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15656         oal_expect_entry_count 4
15657
15658         do_facet ost1 lctl set_param "${param}=0"
15659         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15660         oal_expect_entry_count 4
15661
15662         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15663         oal_expect_entry_count 4
15664 }
15665 run_test 165d "ofd_access_log mask works"
15666
15667 test_169() {
15668         # do directio so as not to populate the page cache
15669         log "creating a 10 Mb file"
15670         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15671         log "starting reads"
15672         dd if=$DIR/$tfile of=/dev/null bs=4096 &
15673         log "truncating the file"
15674         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15675         log "killing dd"
15676         kill %+ || true # reads might have finished
15677         echo "wait until dd is finished"
15678         wait
15679         log "removing the temporary file"
15680         rm -rf $DIR/$tfile || error "tmp file removal failed"
15681 }
15682 run_test 169 "parallel read and truncate should not deadlock"
15683
15684 test_170() {
15685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15686
15687         $LCTL clear     # bug 18514
15688         $LCTL debug_daemon start $TMP/${tfile}_log_good
15689         touch $DIR/$tfile
15690         $LCTL debug_daemon stop
15691         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
15692                 error "sed failed to read log_good"
15693
15694         $LCTL debug_daemon start $TMP/${tfile}_log_good
15695         rm -rf $DIR/$tfile
15696         $LCTL debug_daemon stop
15697
15698         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
15699                error "lctl df log_bad failed"
15700
15701         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15702         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15703
15704         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
15705         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
15706
15707         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
15708                 error "bad_line good_line1 good_line2 are empty"
15709
15710         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15711         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
15712         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15713
15714         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
15715         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15716         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15717
15718         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
15719                 error "bad_line_new good_line_new are empty"
15720
15721         local expected_good=$((good_line1 + good_line2*2))
15722
15723         rm -f $TMP/${tfile}*
15724         # LU-231, short malformed line may not be counted into bad lines
15725         if [ $bad_line -ne $bad_line_new ] &&
15726                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
15727                 error "expected $bad_line bad lines, but got $bad_line_new"
15728                 return 1
15729         fi
15730
15731         if [ $expected_good -ne $good_line_new ]; then
15732                 error "expected $expected_good good lines, but got $good_line_new"
15733                 return 2
15734         fi
15735         true
15736 }
15737 run_test 170 "test lctl df to handle corrupted log ====================="
15738
15739 test_171() { # bug20592
15740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15741
15742         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
15743         $LCTL set_param fail_loc=0x50e
15744         $LCTL set_param fail_val=3000
15745         multiop_bg_pause $DIR/$tfile O_s || true
15746         local MULTIPID=$!
15747         kill -USR1 $MULTIPID
15748         # cause log dump
15749         sleep 3
15750         wait $MULTIPID
15751         if dmesg | grep "recursive fault"; then
15752                 error "caught a recursive fault"
15753         fi
15754         $LCTL set_param fail_loc=0
15755         true
15756 }
15757 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
15758
15759 # it would be good to share it with obdfilter-survey/iokit-libecho code
15760 setup_obdecho_osc () {
15761         local rc=0
15762         local ost_nid=$1
15763         local obdfilter_name=$2
15764         echo "Creating new osc for $obdfilter_name on $ost_nid"
15765         # make sure we can find loopback nid
15766         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
15767
15768         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
15769                            ${obdfilter_name}_osc_UUID || rc=2; }
15770         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
15771                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
15772         return $rc
15773 }
15774
15775 cleanup_obdecho_osc () {
15776         local obdfilter_name=$1
15777         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
15778         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
15779         return 0
15780 }
15781
15782 obdecho_test() {
15783         local OBD=$1
15784         local node=$2
15785         local pages=${3:-64}
15786         local rc=0
15787         local id
15788
15789         local count=10
15790         local obd_size=$(get_obd_size $node $OBD)
15791         local page_size=$(get_page_size $node)
15792         if [[ -n "$obd_size" ]]; then
15793                 local new_count=$((obd_size / (pages * page_size / 1024)))
15794                 [[ $new_count -ge $count ]] || count=$new_count
15795         fi
15796
15797         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
15798         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
15799                            rc=2; }
15800         if [ $rc -eq 0 ]; then
15801             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
15802             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
15803         fi
15804         echo "New object id is $id"
15805         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
15806                            rc=4; }
15807         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
15808                            "test_brw $count w v $pages $id" || rc=4; }
15809         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
15810                            rc=4; }
15811         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
15812                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
15813         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
15814                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
15815         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
15816         return $rc
15817 }
15818
15819 test_180a() {
15820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15821
15822         if ! [ -d /sys/fs/lustre/echo_client ] &&
15823            ! module_loaded obdecho; then
15824                 load_module obdecho/obdecho &&
15825                         stack_trap "rmmod obdecho" EXIT ||
15826                         error "unable to load obdecho on client"
15827         fi
15828
15829         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
15830         local host=$($LCTL get_param -n osc.$osc.import |
15831                      awk '/current_connection:/ { print $2 }' )
15832         local target=$($LCTL get_param -n osc.$osc.import |
15833                        awk '/target:/ { print $2 }' )
15834         target=${target%_UUID}
15835
15836         if [ -n "$target" ]; then
15837                 setup_obdecho_osc $host $target &&
15838                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
15839                         { error "obdecho setup failed with $?"; return; }
15840
15841                 obdecho_test ${target}_osc client ||
15842                         error "obdecho_test failed on ${target}_osc"
15843         else
15844                 $LCTL get_param osc.$osc.import
15845                 error "there is no osc.$osc.import target"
15846         fi
15847 }
15848 run_test 180a "test obdecho on osc"
15849
15850 test_180b() {
15851         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15852         remote_ost_nodsh && skip "remote OST with nodsh"
15853
15854         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15855                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15856                 error "failed to load module obdecho"
15857
15858         local target=$(do_facet ost1 $LCTL dl |
15859                        awk '/obdfilter/ { print $4; exit; }')
15860
15861         if [ -n "$target" ]; then
15862                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
15863         else
15864                 do_facet ost1 $LCTL dl
15865                 error "there is no obdfilter target on ost1"
15866         fi
15867 }
15868 run_test 180b "test obdecho directly on obdfilter"
15869
15870 test_180c() { # LU-2598
15871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15872         remote_ost_nodsh && skip "remote OST with nodsh"
15873         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
15874                 skip "Need MDS version at least 2.4.0"
15875
15876         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15877                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15878                 error "failed to load module obdecho"
15879
15880         local target=$(do_facet ost1 $LCTL dl |
15881                        awk '/obdfilter/ { print $4; exit; }')
15882
15883         if [ -n "$target" ]; then
15884                 local pages=16384 # 64MB bulk I/O RPC size
15885
15886                 obdecho_test "$target" ost1 "$pages" ||
15887                         error "obdecho_test with pages=$pages failed with $?"
15888         else
15889                 do_facet ost1 $LCTL dl
15890                 error "there is no obdfilter target on ost1"
15891         fi
15892 }
15893 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
15894
15895 test_181() { # bug 22177
15896         test_mkdir $DIR/$tdir
15897         # create enough files to index the directory
15898         createmany -o $DIR/$tdir/foobar 4000
15899         # print attributes for debug purpose
15900         lsattr -d .
15901         # open dir
15902         multiop_bg_pause $DIR/$tdir D_Sc || return 1
15903         MULTIPID=$!
15904         # remove the files & current working dir
15905         unlinkmany $DIR/$tdir/foobar 4000
15906         rmdir $DIR/$tdir
15907         kill -USR1 $MULTIPID
15908         wait $MULTIPID
15909         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
15910         return 0
15911 }
15912 run_test 181 "Test open-unlinked dir ========================"
15913
15914 test_182() {
15915         local fcount=1000
15916         local tcount=10
15917
15918         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15919
15920         $LCTL set_param mdc.*.rpc_stats=clear
15921
15922         for (( i = 0; i < $tcount; i++ )) ; do
15923                 mkdir $DIR/$tdir/$i
15924         done
15925
15926         for (( i = 0; i < $tcount; i++ )) ; do
15927                 createmany -o $DIR/$tdir/$i/f- $fcount &
15928         done
15929         wait
15930
15931         for (( i = 0; i < $tcount; i++ )) ; do
15932                 unlinkmany $DIR/$tdir/$i/f- $fcount &
15933         done
15934         wait
15935
15936         $LCTL get_param mdc.*.rpc_stats
15937
15938         rm -rf $DIR/$tdir
15939 }
15940 run_test 182 "Test parallel modify metadata operations ================"
15941
15942 test_183() { # LU-2275
15943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15944         remote_mds_nodsh && skip "remote MDS with nodsh"
15945         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
15946                 skip "Need MDS version at least 2.3.56"
15947
15948         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15949         echo aaa > $DIR/$tdir/$tfile
15950
15951 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
15952         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
15953
15954         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
15955         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
15956
15957         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
15958
15959         # Flush negative dentry cache
15960         touch $DIR/$tdir/$tfile
15961
15962         # We are not checking for any leaked references here, they'll
15963         # become evident next time we do cleanup with module unload.
15964         rm -rf $DIR/$tdir
15965 }
15966 run_test 183 "No crash or request leak in case of strange dispositions ========"
15967
15968 # test suite 184 is for LU-2016, LU-2017
15969 test_184a() {
15970         check_swap_layouts_support
15971
15972         dir0=$DIR/$tdir/$testnum
15973         test_mkdir -p -c1 $dir0
15974         ref1=/etc/passwd
15975         ref2=/etc/group
15976         file1=$dir0/f1
15977         file2=$dir0/f2
15978         $LFS setstripe -c1 $file1
15979         cp $ref1 $file1
15980         $LFS setstripe -c2 $file2
15981         cp $ref2 $file2
15982         gen1=$($LFS getstripe -g $file1)
15983         gen2=$($LFS getstripe -g $file2)
15984
15985         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
15986         gen=$($LFS getstripe -g $file1)
15987         [[ $gen1 != $gen ]] ||
15988                 "Layout generation on $file1 does not change"
15989         gen=$($LFS getstripe -g $file2)
15990         [[ $gen2 != $gen ]] ||
15991                 "Layout generation on $file2 does not change"
15992
15993         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
15994         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
15995
15996         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
15997 }
15998 run_test 184a "Basic layout swap"
15999
16000 test_184b() {
16001         check_swap_layouts_support
16002
16003         dir0=$DIR/$tdir/$testnum
16004         mkdir -p $dir0 || error "creating dir $dir0"
16005         file1=$dir0/f1
16006         file2=$dir0/f2
16007         file3=$dir0/f3
16008         dir1=$dir0/d1
16009         dir2=$dir0/d2
16010         mkdir $dir1 $dir2
16011         $LFS setstripe -c1 $file1
16012         $LFS setstripe -c2 $file2
16013         $LFS setstripe -c1 $file3
16014         chown $RUNAS_ID $file3
16015         gen1=$($LFS getstripe -g $file1)
16016         gen2=$($LFS getstripe -g $file2)
16017
16018         $LFS swap_layouts $dir1 $dir2 &&
16019                 error "swap of directories layouts should fail"
16020         $LFS swap_layouts $dir1 $file1 &&
16021                 error "swap of directory and file layouts should fail"
16022         $RUNAS $LFS swap_layouts $file1 $file2 &&
16023                 error "swap of file we cannot write should fail"
16024         $LFS swap_layouts $file1 $file3 &&
16025                 error "swap of file with different owner should fail"
16026         /bin/true # to clear error code
16027 }
16028 run_test 184b "Forbidden layout swap (will generate errors)"
16029
16030 test_184c() {
16031         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
16032         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
16033         check_swap_layouts_support
16034         check_swap_layout_no_dom $DIR
16035
16036         local dir0=$DIR/$tdir/$testnum
16037         mkdir -p $dir0 || error "creating dir $dir0"
16038
16039         local ref1=$dir0/ref1
16040         local ref2=$dir0/ref2
16041         local file1=$dir0/file1
16042         local file2=$dir0/file2
16043         # create a file large enough for the concurrent test
16044         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
16045         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
16046         echo "ref file size: ref1($(stat -c %s $ref1))," \
16047              "ref2($(stat -c %s $ref2))"
16048
16049         cp $ref2 $file2
16050         dd if=$ref1 of=$file1 bs=16k &
16051         local DD_PID=$!
16052
16053         # Make sure dd starts to copy file, but wait at most 5 seconds
16054         local loops=0
16055         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
16056
16057         $LFS swap_layouts $file1 $file2
16058         local rc=$?
16059         wait $DD_PID
16060         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16061         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16062
16063         # how many bytes copied before swapping layout
16064         local copied=$(stat -c %s $file2)
16065         local remaining=$(stat -c %s $ref1)
16066         remaining=$((remaining - copied))
16067         echo "Copied $copied bytes before swapping layout..."
16068
16069         cmp -n $copied $file1 $ref2 | grep differ &&
16070                 error "Content mismatch [0, $copied) of ref2 and file1"
16071         cmp -n $copied $file2 $ref1 ||
16072                 error "Content mismatch [0, $copied) of ref1 and file2"
16073         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16074                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16075
16076         # clean up
16077         rm -f $ref1 $ref2 $file1 $file2
16078 }
16079 run_test 184c "Concurrent write and layout swap"
16080
16081 test_184d() {
16082         check_swap_layouts_support
16083         check_swap_layout_no_dom $DIR
16084         [ -z "$(which getfattr 2>/dev/null)" ] &&
16085                 skip_env "no getfattr command"
16086
16087         local file1=$DIR/$tdir/$tfile-1
16088         local file2=$DIR/$tdir/$tfile-2
16089         local file3=$DIR/$tdir/$tfile-3
16090         local lovea1
16091         local lovea2
16092
16093         mkdir -p $DIR/$tdir
16094         touch $file1 || error "create $file1 failed"
16095         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16096                 error "create $file2 failed"
16097         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16098                 error "create $file3 failed"
16099         lovea1=$(get_layout_param $file1)
16100
16101         $LFS swap_layouts $file2 $file3 ||
16102                 error "swap $file2 $file3 layouts failed"
16103         $LFS swap_layouts $file1 $file2 ||
16104                 error "swap $file1 $file2 layouts failed"
16105
16106         lovea2=$(get_layout_param $file2)
16107         echo "$lovea1"
16108         echo "$lovea2"
16109         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16110
16111         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16112         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16113 }
16114 run_test 184d "allow stripeless layouts swap"
16115
16116 test_184e() {
16117         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16118                 skip "Need MDS version at least 2.6.94"
16119         check_swap_layouts_support
16120         check_swap_layout_no_dom $DIR
16121         [ -z "$(which getfattr 2>/dev/null)" ] &&
16122                 skip_env "no getfattr command"
16123
16124         local file1=$DIR/$tdir/$tfile-1
16125         local file2=$DIR/$tdir/$tfile-2
16126         local file3=$DIR/$tdir/$tfile-3
16127         local lovea
16128
16129         mkdir -p $DIR/$tdir
16130         touch $file1 || error "create $file1 failed"
16131         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16132                 error "create $file2 failed"
16133         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16134                 error "create $file3 failed"
16135
16136         $LFS swap_layouts $file1 $file2 ||
16137                 error "swap $file1 $file2 layouts failed"
16138
16139         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16140         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16141
16142         echo 123 > $file1 || error "Should be able to write into $file1"
16143
16144         $LFS swap_layouts $file1 $file3 ||
16145                 error "swap $file1 $file3 layouts failed"
16146
16147         echo 123 > $file1 || error "Should be able to write into $file1"
16148
16149         rm -rf $file1 $file2 $file3
16150 }
16151 run_test 184e "Recreate layout after stripeless layout swaps"
16152
16153 test_184f() {
16154         # Create a file with name longer than sizeof(struct stat) ==
16155         # 144 to see if we can get chars from the file name to appear
16156         # in the returned striping. Note that 'f' == 0x66.
16157         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16158
16159         mkdir -p $DIR/$tdir
16160         mcreate $DIR/$tdir/$file
16161         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16162                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16163         fi
16164 }
16165 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16166
16167 test_185() { # LU-2441
16168         # LU-3553 - no volatile file support in old servers
16169         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16170                 skip "Need MDS version at least 2.3.60"
16171
16172         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16173         touch $DIR/$tdir/spoo
16174         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16175         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16176                 error "cannot create/write a volatile file"
16177         [ "$FILESET" == "" ] &&
16178         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16179                 error "FID is still valid after close"
16180
16181         multiop_bg_pause $DIR/$tdir vVw4096_c
16182         local multi_pid=$!
16183
16184         local OLD_IFS=$IFS
16185         IFS=":"
16186         local fidv=($fid)
16187         IFS=$OLD_IFS
16188         # assume that the next FID for this client is sequential, since stdout
16189         # is unfortunately eaten by multiop_bg_pause
16190         local n=$((${fidv[1]} + 1))
16191         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16192         if [ "$FILESET" == "" ]; then
16193                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16194                         error "FID is missing before close"
16195         fi
16196         kill -USR1 $multi_pid
16197         # 1 second delay, so if mtime change we will see it
16198         sleep 1
16199         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16200         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16201 }
16202 run_test 185 "Volatile file support"
16203
16204 function create_check_volatile() {
16205         local idx=$1
16206         local tgt
16207
16208         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16209         local PID=$!
16210         sleep 1
16211         local FID=$(cat /tmp/${tfile}.fid)
16212         [ "$FID" == "" ] && error "can't get FID for volatile"
16213         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16214         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16215         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16216         kill -USR1 $PID
16217         wait
16218         sleep 1
16219         cancel_lru_locks mdc # flush opencache
16220         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16221         return 0
16222 }
16223
16224 test_185a(){
16225         # LU-12516 - volatile creation via .lustre
16226         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16227                 skip "Need MDS version at least 2.3.55"
16228
16229         create_check_volatile 0
16230         [ $MDSCOUNT -lt 2 ] && return 0
16231
16232         # DNE case
16233         create_check_volatile 1
16234
16235         return 0
16236 }
16237 run_test 185a "Volatile file creation in .lustre/fid/"
16238
16239 test_187a() {
16240         remote_mds_nodsh && skip "remote MDS with nodsh"
16241         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16242                 skip "Need MDS version at least 2.3.0"
16243
16244         local dir0=$DIR/$tdir/$testnum
16245         mkdir -p $dir0 || error "creating dir $dir0"
16246
16247         local file=$dir0/file1
16248         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16249         local dv1=$($LFS data_version $file)
16250         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16251         local dv2=$($LFS data_version $file)
16252         [[ $dv1 != $dv2 ]] ||
16253                 error "data version did not change on write $dv1 == $dv2"
16254
16255         # clean up
16256         rm -f $file1
16257 }
16258 run_test 187a "Test data version change"
16259
16260 test_187b() {
16261         remote_mds_nodsh && skip "remote MDS with nodsh"
16262         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16263                 skip "Need MDS version at least 2.3.0"
16264
16265         local dir0=$DIR/$tdir/$testnum
16266         mkdir -p $dir0 || error "creating dir $dir0"
16267
16268         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16269         [[ ${DV[0]} != ${DV[1]} ]] ||
16270                 error "data version did not change on write"\
16271                       " ${DV[0]} == ${DV[1]}"
16272
16273         # clean up
16274         rm -f $file1
16275 }
16276 run_test 187b "Test data version change on volatile file"
16277
16278 test_200() {
16279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16280         remote_mgs_nodsh && skip "remote MGS with nodsh"
16281         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16282
16283         local POOL=${POOL:-cea1}
16284         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16285         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16286         # Pool OST targets
16287         local first_ost=0
16288         local last_ost=$(($OSTCOUNT - 1))
16289         local ost_step=2
16290         local ost_list=$(seq $first_ost $ost_step $last_ost)
16291         local ost_range="$first_ost $last_ost $ost_step"
16292         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16293         local file_dir=$POOL_ROOT/file_tst
16294         local subdir=$test_path/subdir
16295         local rc=0
16296
16297         while : ; do
16298                 # former test_200a test_200b
16299                 pool_add $POOL                          || { rc=$? ; break; }
16300                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16301                 # former test_200c test_200d
16302                 mkdir -p $test_path
16303                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16304                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16305                 mkdir -p $subdir
16306                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16307                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16308                                                         || { rc=$? ; break; }
16309                 # former test_200e test_200f
16310                 local files=$((OSTCOUNT*3))
16311                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16312                                                         || { rc=$? ; break; }
16313                 pool_create_files $POOL $file_dir $files "$ost_list" \
16314                                                         || { rc=$? ; break; }
16315                 # former test_200g test_200h
16316                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16317                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16318
16319                 # former test_201a test_201b test_201c
16320                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16321
16322                 local f=$test_path/$tfile
16323                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16324                 pool_remove $POOL $f                    || { rc=$? ; break; }
16325                 break
16326         done
16327
16328         destroy_test_pools
16329
16330         return $rc
16331 }
16332 run_test 200 "OST pools"
16333
16334 # usage: default_attr <count | size | offset>
16335 default_attr() {
16336         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16337 }
16338
16339 # usage: check_default_stripe_attr
16340 check_default_stripe_attr() {
16341         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16342         case $1 in
16343         --stripe-count|-c)
16344                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16345         --stripe-size|-S)
16346                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16347         --stripe-index|-i)
16348                 EXPECTED=-1;;
16349         *)
16350                 error "unknown getstripe attr '$1'"
16351         esac
16352
16353         [ $ACTUAL == $EXPECTED ] ||
16354                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16355 }
16356
16357 test_204a() {
16358         test_mkdir $DIR/$tdir
16359         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16360
16361         check_default_stripe_attr --stripe-count
16362         check_default_stripe_attr --stripe-size
16363         check_default_stripe_attr --stripe-index
16364 }
16365 run_test 204a "Print default stripe attributes"
16366
16367 test_204b() {
16368         test_mkdir $DIR/$tdir
16369         $LFS setstripe --stripe-count 1 $DIR/$tdir
16370
16371         check_default_stripe_attr --stripe-size
16372         check_default_stripe_attr --stripe-index
16373 }
16374 run_test 204b "Print default stripe size and offset"
16375
16376 test_204c() {
16377         test_mkdir $DIR/$tdir
16378         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16379
16380         check_default_stripe_attr --stripe-count
16381         check_default_stripe_attr --stripe-index
16382 }
16383 run_test 204c "Print default stripe count and offset"
16384
16385 test_204d() {
16386         test_mkdir $DIR/$tdir
16387         $LFS setstripe --stripe-index 0 $DIR/$tdir
16388
16389         check_default_stripe_attr --stripe-count
16390         check_default_stripe_attr --stripe-size
16391 }
16392 run_test 204d "Print default stripe count and size"
16393
16394 test_204e() {
16395         test_mkdir $DIR/$tdir
16396         $LFS setstripe -d $DIR/$tdir
16397
16398         check_default_stripe_attr --stripe-count --raw
16399         check_default_stripe_attr --stripe-size --raw
16400         check_default_stripe_attr --stripe-index --raw
16401 }
16402 run_test 204e "Print raw stripe attributes"
16403
16404 test_204f() {
16405         test_mkdir $DIR/$tdir
16406         $LFS setstripe --stripe-count 1 $DIR/$tdir
16407
16408         check_default_stripe_attr --stripe-size --raw
16409         check_default_stripe_attr --stripe-index --raw
16410 }
16411 run_test 204f "Print raw stripe size and offset"
16412
16413 test_204g() {
16414         test_mkdir $DIR/$tdir
16415         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16416
16417         check_default_stripe_attr --stripe-count --raw
16418         check_default_stripe_attr --stripe-index --raw
16419 }
16420 run_test 204g "Print raw stripe count and offset"
16421
16422 test_204h() {
16423         test_mkdir $DIR/$tdir
16424         $LFS setstripe --stripe-index 0 $DIR/$tdir
16425
16426         check_default_stripe_attr --stripe-count --raw
16427         check_default_stripe_attr --stripe-size --raw
16428 }
16429 run_test 204h "Print raw stripe count and size"
16430
16431 # Figure out which job scheduler is being used, if any,
16432 # or use a fake one
16433 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16434         JOBENV=SLURM_JOB_ID
16435 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16436         JOBENV=LSB_JOBID
16437 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16438         JOBENV=PBS_JOBID
16439 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16440         JOBENV=LOADL_STEP_ID
16441 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16442         JOBENV=JOB_ID
16443 else
16444         $LCTL list_param jobid_name > /dev/null 2>&1
16445         if [ $? -eq 0 ]; then
16446                 JOBENV=nodelocal
16447         else
16448                 JOBENV=FAKE_JOBID
16449         fi
16450 fi
16451 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16452
16453 verify_jobstats() {
16454         local cmd=($1)
16455         shift
16456         local facets="$@"
16457
16458 # we don't really need to clear the stats for this test to work, since each
16459 # command has a unique jobid, but it makes debugging easier if needed.
16460 #       for facet in $facets; do
16461 #               local dev=$(convert_facet2label $facet)
16462 #               # clear old jobstats
16463 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16464 #       done
16465
16466         # use a new JobID for each test, or we might see an old one
16467         [ "$JOBENV" = "FAKE_JOBID" ] &&
16468                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16469
16470         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16471
16472         [ "$JOBENV" = "nodelocal" ] && {
16473                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16474                 $LCTL set_param jobid_name=$FAKE_JOBID
16475                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16476         }
16477
16478         log "Test: ${cmd[*]}"
16479         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16480
16481         if [ $JOBENV = "FAKE_JOBID" ]; then
16482                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16483         else
16484                 ${cmd[*]}
16485         fi
16486
16487         # all files are created on OST0000
16488         for facet in $facets; do
16489                 local stats="*.$(convert_facet2label $facet).job_stats"
16490
16491                 # strip out libtool wrappers for in-tree executables
16492                 if [ $(do_facet $facet lctl get_param $stats |
16493                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16494                         do_facet $facet lctl get_param $stats
16495                         error "No jobstats for $JOBVAL found on $facet::$stats"
16496                 fi
16497         done
16498 }
16499
16500 jobstats_set() {
16501         local new_jobenv=$1
16502
16503         set_persistent_param_and_check client "jobid_var" \
16504                 "$FSNAME.sys.jobid_var" $new_jobenv
16505 }
16506
16507 test_205a() { # Job stats
16508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16509         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
16510                 skip "Need MDS version with at least 2.7.1"
16511         remote_mgs_nodsh && skip "remote MGS with nodsh"
16512         remote_mds_nodsh && skip "remote MDS with nodsh"
16513         remote_ost_nodsh && skip "remote OST with nodsh"
16514         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
16515                 skip "Server doesn't support jobstats"
16516         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
16517
16518         local old_jobenv=$($LCTL get_param -n jobid_var)
16519         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
16520
16521         if [[ $PERM_CMD == *"set_param -P"* ]]; then
16522                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
16523         else
16524                 stack_trap "do_facet mgs $PERM_CMD \
16525                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
16526         fi
16527         changelog_register
16528
16529         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
16530                                 mdt.*.job_cleanup_interval | head -n 1)
16531         local new_interval=5
16532         do_facet $SINGLEMDS \
16533                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
16534         stack_trap "do_facet $SINGLEMDS \
16535                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
16536         local start=$SECONDS
16537
16538         local cmd
16539         # mkdir
16540         cmd="mkdir $DIR/$tdir"
16541         verify_jobstats "$cmd" "$SINGLEMDS"
16542         # rmdir
16543         cmd="rmdir $DIR/$tdir"
16544         verify_jobstats "$cmd" "$SINGLEMDS"
16545         # mkdir on secondary MDT
16546         if [ $MDSCOUNT -gt 1 ]; then
16547                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
16548                 verify_jobstats "$cmd" "mds2"
16549         fi
16550         # mknod
16551         cmd="mknod $DIR/$tfile c 1 3"
16552         verify_jobstats "$cmd" "$SINGLEMDS"
16553         # unlink
16554         cmd="rm -f $DIR/$tfile"
16555         verify_jobstats "$cmd" "$SINGLEMDS"
16556         # create all files on OST0000 so verify_jobstats can find OST stats
16557         # open & close
16558         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
16559         verify_jobstats "$cmd" "$SINGLEMDS"
16560         # setattr
16561         cmd="touch $DIR/$tfile"
16562         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16563         # write
16564         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
16565         verify_jobstats "$cmd" "ost1"
16566         # read
16567         cancel_lru_locks osc
16568         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
16569         verify_jobstats "$cmd" "ost1"
16570         # truncate
16571         cmd="$TRUNCATE $DIR/$tfile 0"
16572         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16573         # rename
16574         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
16575         verify_jobstats "$cmd" "$SINGLEMDS"
16576         # jobstats expiry - sleep until old stats should be expired
16577         local left=$((new_interval + 5 - (SECONDS - start)))
16578         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
16579                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
16580                         "0" $left
16581         cmd="mkdir $DIR/$tdir.expire"
16582         verify_jobstats "$cmd" "$SINGLEMDS"
16583         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
16584             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
16585
16586         # Ensure that jobid are present in changelog (if supported by MDS)
16587         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
16588                 changelog_dump | tail -10
16589                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
16590                 [ $jobids -eq 9 ] ||
16591                         error "Wrong changelog jobid count $jobids != 9"
16592
16593                 # LU-5862
16594                 JOBENV="disable"
16595                 jobstats_set $JOBENV
16596                 touch $DIR/$tfile
16597                 changelog_dump | grep $tfile
16598                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
16599                 [ $jobids -eq 0 ] ||
16600                         error "Unexpected jobids when jobid_var=$JOBENV"
16601         fi
16602
16603         # test '%j' access to environment variable - if supported
16604         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
16605                 JOBENV="JOBCOMPLEX"
16606                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16607
16608                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16609         fi
16610
16611         # test '%j' access to per-session jobid - if supported
16612         if lctl list_param jobid_this_session > /dev/null 2>&1
16613         then
16614                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
16615                 lctl set_param jobid_this_session=$USER
16616
16617                 JOBENV="JOBCOMPLEX"
16618                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16619
16620                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16621         fi
16622 }
16623 run_test 205a "Verify job stats"
16624
16625 # LU-13117, LU-13597
16626 test_205b() {
16627         job_stats="mdt.*.job_stats"
16628         $LCTL set_param $job_stats=clear
16629         # Setting jobid_var to USER might not be supported
16630         $LCTL set_param jobid_var=USER || true
16631         $LCTL set_param jobid_name="%e.%u"
16632         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16633         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16634                 grep "job_id:.*foolish" &&
16635                         error "Unexpected jobid found"
16636         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16637                 grep "open:.*min.*max.*sum" ||
16638                         error "wrong job_stats format found"
16639 }
16640 run_test 205b "Verify job stats jobid and output format"
16641
16642 # LU-13733
16643 test_205c() {
16644         $LCTL set_param llite.*.stats=0
16645         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
16646         $LCTL get_param llite.*.stats
16647         $LCTL get_param llite.*.stats | grep \
16648                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
16649                         error "wrong client stats format found"
16650 }
16651 run_test 205c "Verify client stats format"
16652
16653 # LU-1480, LU-1773 and LU-1657
16654 test_206() {
16655         mkdir -p $DIR/$tdir
16656         $LFS setstripe -c -1 $DIR/$tdir
16657 #define OBD_FAIL_LOV_INIT 0x1403
16658         $LCTL set_param fail_loc=0xa0001403
16659         $LCTL set_param fail_val=1
16660         touch $DIR/$tdir/$tfile || true
16661 }
16662 run_test 206 "fail lov_init_raid0() doesn't lbug"
16663
16664 test_207a() {
16665         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16666         local fsz=`stat -c %s $DIR/$tfile`
16667         cancel_lru_locks mdc
16668
16669         # do not return layout in getattr intent
16670 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16671         $LCTL set_param fail_loc=0x170
16672         local sz=`stat -c %s $DIR/$tfile`
16673
16674         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16675
16676         rm -rf $DIR/$tfile
16677 }
16678 run_test 207a "can refresh layout at glimpse"
16679
16680 test_207b() {
16681         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16682         local cksum=`md5sum $DIR/$tfile`
16683         local fsz=`stat -c %s $DIR/$tfile`
16684         cancel_lru_locks mdc
16685         cancel_lru_locks osc
16686
16687         # do not return layout in getattr intent
16688 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16689         $LCTL set_param fail_loc=0x171
16690
16691         # it will refresh layout after the file is opened but before read issues
16692         echo checksum is "$cksum"
16693         echo "$cksum" |md5sum -c --quiet || error "file differs"
16694
16695         rm -rf $DIR/$tfile
16696 }
16697 run_test 207b "can refresh layout at open"
16698
16699 test_208() {
16700         # FIXME: in this test suite, only RD lease is used. This is okay
16701         # for now as only exclusive open is supported. After generic lease
16702         # is done, this test suite should be revised. - Jinshan
16703
16704         remote_mds_nodsh && skip "remote MDS with nodsh"
16705         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
16706                 skip "Need MDS version at least 2.4.52"
16707
16708         echo "==== test 1: verify get lease work"
16709         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
16710
16711         echo "==== test 2: verify lease can be broken by upcoming open"
16712         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16713         local PID=$!
16714         sleep 1
16715
16716         $MULTIOP $DIR/$tfile oO_RDONLY:c
16717         kill -USR1 $PID && wait $PID || error "break lease error"
16718
16719         echo "==== test 3: verify lease can't be granted if an open already exists"
16720         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
16721         local PID=$!
16722         sleep 1
16723
16724         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
16725         kill -USR1 $PID && wait $PID || error "open file error"
16726
16727         echo "==== test 4: lease can sustain over recovery"
16728         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16729         PID=$!
16730         sleep 1
16731
16732         fail mds1
16733
16734         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
16735
16736         echo "==== test 5: lease broken can't be regained by replay"
16737         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16738         PID=$!
16739         sleep 1
16740
16741         # open file to break lease and then recovery
16742         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
16743         fail mds1
16744
16745         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
16746
16747         rm -f $DIR/$tfile
16748 }
16749 run_test 208 "Exclusive open"
16750
16751 test_209() {
16752         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
16753                 skip_env "must have disp_stripe"
16754
16755         touch $DIR/$tfile
16756         sync; sleep 5; sync;
16757
16758         echo 3 > /proc/sys/vm/drop_caches
16759         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16760                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16761         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16762
16763         # open/close 500 times
16764         for i in $(seq 500); do
16765                 cat $DIR/$tfile
16766         done
16767
16768         echo 3 > /proc/sys/vm/drop_caches
16769         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16770                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16771         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16772
16773         echo "before: $req_before, after: $req_after"
16774         [ $((req_after - req_before)) -ge 300 ] &&
16775                 error "open/close requests are not freed"
16776         return 0
16777 }
16778 run_test 209 "read-only open/close requests should be freed promptly"
16779
16780 test_210() {
16781         local pid
16782
16783         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
16784         pid=$!
16785         sleep 1
16786
16787         $LFS getstripe $DIR/$tfile
16788         kill -USR1 $pid
16789         wait $pid || error "multiop failed"
16790
16791         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16792         pid=$!
16793         sleep 1
16794
16795         $LFS getstripe $DIR/$tfile
16796         kill -USR1 $pid
16797         wait $pid || error "multiop failed"
16798 }
16799 run_test 210 "lfs getstripe does not break leases"
16800
16801 test_212() {
16802         size=`date +%s`
16803         size=$((size % 8192 + 1))
16804         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
16805         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
16806         rm -f $DIR/f212 $DIR/f212.xyz
16807 }
16808 run_test 212 "Sendfile test ============================================"
16809
16810 test_213() {
16811         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
16812         cancel_lru_locks osc
16813         lctl set_param fail_loc=0x8000040f
16814         # generate a read lock
16815         cat $DIR/$tfile > /dev/null
16816         # write to the file, it will try to cancel the above read lock.
16817         cat /etc/hosts >> $DIR/$tfile
16818 }
16819 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
16820
16821 test_214() { # for bug 20133
16822         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
16823         for (( i=0; i < 340; i++ )) ; do
16824                 touch $DIR/$tdir/d214c/a$i
16825         done
16826
16827         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
16828         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
16829         ls $DIR/d214c || error "ls $DIR/d214c failed"
16830         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
16831         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
16832 }
16833 run_test 214 "hash-indexed directory test - bug 20133"
16834
16835 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
16836 create_lnet_proc_files() {
16837         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
16838 }
16839
16840 # counterpart of create_lnet_proc_files
16841 remove_lnet_proc_files() {
16842         rm -f $TMP/lnet_$1.sys
16843 }
16844
16845 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16846 # 3rd arg as regexp for body
16847 check_lnet_proc_stats() {
16848         local l=$(cat "$TMP/lnet_$1" |wc -l)
16849         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
16850
16851         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
16852 }
16853
16854 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16855 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
16856 # optional and can be regexp for 2nd line (lnet.routes case)
16857 check_lnet_proc_entry() {
16858         local blp=2          # blp stands for 'position of 1st line of body'
16859         [ -z "$5" ] || blp=3 # lnet.routes case
16860
16861         local l=$(cat "$TMP/lnet_$1" |wc -l)
16862         # subtracting one from $blp because the body can be empty
16863         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
16864
16865         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
16866                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
16867
16868         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
16869                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
16870
16871         # bail out if any unexpected line happened
16872         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
16873         [ "$?" != 0 ] || error "$2 misformatted"
16874 }
16875
16876 test_215() { # for bugs 18102, 21079, 21517
16877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16878
16879         local N='(0|[1-9][0-9]*)'       # non-negative numeric
16880         local P='[1-9][0-9]*'           # positive numeric
16881         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
16882         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
16883         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
16884         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
16885
16886         local L1 # regexp for 1st line
16887         local L2 # regexp for 2nd line (optional)
16888         local BR # regexp for the rest (body)
16889
16890         # lnet.stats should look as 11 space-separated non-negative numerics
16891         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
16892         create_lnet_proc_files "stats"
16893         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
16894         remove_lnet_proc_files "stats"
16895
16896         # lnet.routes should look like this:
16897         # Routing disabled/enabled
16898         # net hops priority state router
16899         # where net is a string like tcp0, hops > 0, priority >= 0,
16900         # state is up/down,
16901         # router is a string like 192.168.1.1@tcp2
16902         L1="^Routing (disabled|enabled)$"
16903         L2="^net +hops +priority +state +router$"
16904         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
16905         create_lnet_proc_files "routes"
16906         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
16907         remove_lnet_proc_files "routes"
16908
16909         # lnet.routers should look like this:
16910         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
16911         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
16912         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
16913         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
16914         L1="^ref +rtr_ref +alive +router$"
16915         BR="^$P +$P +(up|down) +$NID$"
16916         create_lnet_proc_files "routers"
16917         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
16918         remove_lnet_proc_files "routers"
16919
16920         # lnet.peers should look like this:
16921         # nid refs state last max rtr min tx min queue
16922         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
16923         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
16924         # numeric (0 or >0 or <0), queue >= 0.
16925         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
16926         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
16927         create_lnet_proc_files "peers"
16928         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
16929         remove_lnet_proc_files "peers"
16930
16931         # lnet.buffers  should look like this:
16932         # pages count credits min
16933         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
16934         L1="^pages +count +credits +min$"
16935         BR="^ +$N +$N +$I +$I$"
16936         create_lnet_proc_files "buffers"
16937         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
16938         remove_lnet_proc_files "buffers"
16939
16940         # lnet.nis should look like this:
16941         # nid status alive refs peer rtr max tx min
16942         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
16943         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
16944         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
16945         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
16946         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
16947         create_lnet_proc_files "nis"
16948         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
16949         remove_lnet_proc_files "nis"
16950
16951         # can we successfully write to lnet.stats?
16952         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
16953 }
16954 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
16955
16956 test_216() { # bug 20317
16957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16958         remote_ost_nodsh && skip "remote OST with nodsh"
16959
16960         local node
16961         local facets=$(get_facets OST)
16962         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16963
16964         save_lustre_params client "osc.*.contention_seconds" > $p
16965         save_lustre_params $facets \
16966                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
16967         save_lustre_params $facets \
16968                 "ldlm.namespaces.filter-*.contended_locks" >> $p
16969         save_lustre_params $facets \
16970                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
16971         clear_stats osc.*.osc_stats
16972
16973         # agressive lockless i/o settings
16974         do_nodes $(comma_list $(osts_nodes)) \
16975                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
16976                         ldlm.namespaces.filter-*.contended_locks=0 \
16977                         ldlm.namespaces.filter-*.contention_seconds=60"
16978         lctl set_param -n osc.*.contention_seconds=60
16979
16980         $DIRECTIO write $DIR/$tfile 0 10 4096
16981         $CHECKSTAT -s 40960 $DIR/$tfile
16982
16983         # disable lockless i/o
16984         do_nodes $(comma_list $(osts_nodes)) \
16985                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
16986                         ldlm.namespaces.filter-*.contended_locks=32 \
16987                         ldlm.namespaces.filter-*.contention_seconds=0"
16988         lctl set_param -n osc.*.contention_seconds=0
16989         clear_stats osc.*.osc_stats
16990
16991         dd if=/dev/zero of=$DIR/$tfile count=0
16992         $CHECKSTAT -s 0 $DIR/$tfile
16993
16994         restore_lustre_params <$p
16995         rm -f $p
16996         rm $DIR/$tfile
16997 }
16998 run_test 216 "check lockless direct write updates file size and kms correctly"
16999
17000 test_217() { # bug 22430
17001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17002
17003         local node
17004         local nid
17005
17006         for node in $(nodes_list); do
17007                 nid=$(host_nids_address $node $NETTYPE)
17008                 if [[ $nid = *-* ]] ; then
17009                         echo "lctl ping $(h2nettype $nid)"
17010                         lctl ping $(h2nettype $nid)
17011                 else
17012                         echo "skipping $node (no hyphen detected)"
17013                 fi
17014         done
17015 }
17016 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
17017
17018 test_218() {
17019        # do directio so as not to populate the page cache
17020        log "creating a 10 Mb file"
17021        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
17022        log "starting reads"
17023        dd if=$DIR/$tfile of=/dev/null bs=4096 &
17024        log "truncating the file"
17025        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
17026        log "killing dd"
17027        kill %+ || true # reads might have finished
17028        echo "wait until dd is finished"
17029        wait
17030        log "removing the temporary file"
17031        rm -rf $DIR/$tfile || error "tmp file removal failed"
17032 }
17033 run_test 218 "parallel read and truncate should not deadlock"
17034
17035 test_219() {
17036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17037
17038         # write one partial page
17039         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
17040         # set no grant so vvp_io_commit_write will do sync write
17041         $LCTL set_param fail_loc=0x411
17042         # write a full page at the end of file
17043         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
17044
17045         $LCTL set_param fail_loc=0
17046         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
17047         $LCTL set_param fail_loc=0x411
17048         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
17049
17050         # LU-4201
17051         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17052         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17053 }
17054 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17055
17056 test_220() { #LU-325
17057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17058         remote_ost_nodsh && skip "remote OST with nodsh"
17059         remote_mds_nodsh && skip "remote MDS with nodsh"
17060         remote_mgs_nodsh && skip "remote MGS with nodsh"
17061
17062         local OSTIDX=0
17063
17064         # create on MDT0000 so the last_id and next_id are correct
17065         mkdir $DIR/$tdir
17066         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17067         OST=${OST%_UUID}
17068
17069         # on the mdt's osc
17070         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17071         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17072                         osp.$mdtosc_proc1.prealloc_last_id)
17073         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17074                         osp.$mdtosc_proc1.prealloc_next_id)
17075
17076         $LFS df -i
17077
17078         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17079         #define OBD_FAIL_OST_ENOINO              0x229
17080         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17081         create_pool $FSNAME.$TESTNAME || return 1
17082         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17083
17084         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17085
17086         MDSOBJS=$((last_id - next_id))
17087         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17088
17089         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17090         echo "OST still has $count kbytes free"
17091
17092         echo "create $MDSOBJS files @next_id..."
17093         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17094
17095         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17096                         osp.$mdtosc_proc1.prealloc_last_id)
17097         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17098                         osp.$mdtosc_proc1.prealloc_next_id)
17099
17100         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17101         $LFS df -i
17102
17103         echo "cleanup..."
17104
17105         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17106         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17107
17108         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17109                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17110         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17111                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17112         echo "unlink $MDSOBJS files @$next_id..."
17113         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17114 }
17115 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17116
17117 test_221() {
17118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17119
17120         dd if=`which date` of=$MOUNT/date oflag=sync
17121         chmod +x $MOUNT/date
17122
17123         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17124         $LCTL set_param fail_loc=0x80001401
17125
17126         $MOUNT/date > /dev/null
17127         rm -f $MOUNT/date
17128 }
17129 run_test 221 "make sure fault and truncate race to not cause OOM"
17130
17131 test_222a () {
17132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17133
17134         rm -rf $DIR/$tdir
17135         test_mkdir $DIR/$tdir
17136         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17137         createmany -o $DIR/$tdir/$tfile 10
17138         cancel_lru_locks mdc
17139         cancel_lru_locks osc
17140         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17141         $LCTL set_param fail_loc=0x31a
17142         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17143         $LCTL set_param fail_loc=0
17144         rm -r $DIR/$tdir
17145 }
17146 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17147
17148 test_222b () {
17149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17150
17151         rm -rf $DIR/$tdir
17152         test_mkdir $DIR/$tdir
17153         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17154         createmany -o $DIR/$tdir/$tfile 10
17155         cancel_lru_locks mdc
17156         cancel_lru_locks osc
17157         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17158         $LCTL set_param fail_loc=0x31a
17159         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17160         $LCTL set_param fail_loc=0
17161 }
17162 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17163
17164 test_223 () {
17165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17166
17167         rm -rf $DIR/$tdir
17168         test_mkdir $DIR/$tdir
17169         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17170         createmany -o $DIR/$tdir/$tfile 10
17171         cancel_lru_locks mdc
17172         cancel_lru_locks osc
17173         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17174         $LCTL set_param fail_loc=0x31b
17175         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17176         $LCTL set_param fail_loc=0
17177         rm -r $DIR/$tdir
17178 }
17179 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17180
17181 test_224a() { # LU-1039, MRP-303
17182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17183
17184         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17185         $LCTL set_param fail_loc=0x508
17186         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17187         $LCTL set_param fail_loc=0
17188         df $DIR
17189 }
17190 run_test 224a "Don't panic on bulk IO failure"
17191
17192 test_224b() { # LU-1039, MRP-303
17193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17194
17195         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17196         cancel_lru_locks osc
17197         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17198         $LCTL set_param fail_loc=0x515
17199         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17200         $LCTL set_param fail_loc=0
17201         df $DIR
17202 }
17203 run_test 224b "Don't panic on bulk IO failure"
17204
17205 test_224c() { # LU-6441
17206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17207         remote_mds_nodsh && skip "remote MDS with nodsh"
17208
17209         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17210         save_writethrough $p
17211         set_cache writethrough on
17212
17213         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17214         local at_max=$($LCTL get_param -n at_max)
17215         local timeout=$($LCTL get_param -n timeout)
17216         local test_at="at_max"
17217         local param_at="$FSNAME.sys.at_max"
17218         local test_timeout="timeout"
17219         local param_timeout="$FSNAME.sys.timeout"
17220
17221         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17222
17223         set_persistent_param_and_check client "$test_at" "$param_at" 0
17224         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17225
17226         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17227         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17228         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17229         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17230         sync
17231         do_facet ost1 "$LCTL set_param fail_loc=0"
17232
17233         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17234         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17235                 $timeout
17236
17237         $LCTL set_param -n $pages_per_rpc
17238         restore_lustre_params < $p
17239         rm -f $p
17240 }
17241 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17242
17243 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17244 test_225a () {
17245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17246         if [ -z ${MDSSURVEY} ]; then
17247                 skip_env "mds-survey not found"
17248         fi
17249         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17250                 skip "Need MDS version at least 2.2.51"
17251
17252         local mds=$(facet_host $SINGLEMDS)
17253         local target=$(do_nodes $mds 'lctl dl' |
17254                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17255
17256         local cmd1="file_count=1000 thrhi=4"
17257         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17258         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17259         local cmd="$cmd1 $cmd2 $cmd3"
17260
17261         rm -f ${TMP}/mds_survey*
17262         echo + $cmd
17263         eval $cmd || error "mds-survey with zero-stripe failed"
17264         cat ${TMP}/mds_survey*
17265         rm -f ${TMP}/mds_survey*
17266 }
17267 run_test 225a "Metadata survey sanity with zero-stripe"
17268
17269 test_225b () {
17270         if [ -z ${MDSSURVEY} ]; then
17271                 skip_env "mds-survey not found"
17272         fi
17273         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17274                 skip "Need MDS version at least 2.2.51"
17275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17276         remote_mds_nodsh && skip "remote MDS with nodsh"
17277         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17278                 skip_env "Need to mount OST to test"
17279         fi
17280
17281         local mds=$(facet_host $SINGLEMDS)
17282         local target=$(do_nodes $mds 'lctl dl' |
17283                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17284
17285         local cmd1="file_count=1000 thrhi=4"
17286         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17287         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17288         local cmd="$cmd1 $cmd2 $cmd3"
17289
17290         rm -f ${TMP}/mds_survey*
17291         echo + $cmd
17292         eval $cmd || error "mds-survey with stripe_count failed"
17293         cat ${TMP}/mds_survey*
17294         rm -f ${TMP}/mds_survey*
17295 }
17296 run_test 225b "Metadata survey sanity with stripe_count = 1"
17297
17298 mcreate_path2fid () {
17299         local mode=$1
17300         local major=$2
17301         local minor=$3
17302         local name=$4
17303         local desc=$5
17304         local path=$DIR/$tdir/$name
17305         local fid
17306         local rc
17307         local fid_path
17308
17309         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17310                 error "cannot create $desc"
17311
17312         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17313         rc=$?
17314         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17315
17316         fid_path=$($LFS fid2path $MOUNT $fid)
17317         rc=$?
17318         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17319
17320         [ "$path" == "$fid_path" ] ||
17321                 error "fid2path returned $fid_path, expected $path"
17322
17323         echo "pass with $path and $fid"
17324 }
17325
17326 test_226a () {
17327         rm -rf $DIR/$tdir
17328         mkdir -p $DIR/$tdir
17329
17330         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17331         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17332         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17333         mcreate_path2fid 0040666 0 0 dir "directory"
17334         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17335         mcreate_path2fid 0100666 0 0 file "regular file"
17336         mcreate_path2fid 0120666 0 0 link "symbolic link"
17337         mcreate_path2fid 0140666 0 0 sock "socket"
17338 }
17339 run_test 226a "call path2fid and fid2path on files of all type"
17340
17341 test_226b () {
17342         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17343
17344         local MDTIDX=1
17345
17346         rm -rf $DIR/$tdir
17347         mkdir -p $DIR/$tdir
17348         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17349                 error "create remote directory failed"
17350         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17351         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17352                                 "character special file (null)"
17353         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17354                                 "character special file (no device)"
17355         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17356         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17357                                 "block special file (loop)"
17358         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17359         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17360         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17361 }
17362 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17363
17364 test_226c () {
17365         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17366         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17367                 skip "Need MDS version at least 2.13.55"
17368
17369         local submnt=/mnt/submnt
17370         local srcfile=/etc/passwd
17371         local dstfile=$submnt/passwd
17372         local path
17373         local fid
17374
17375         rm -rf $DIR/$tdir
17376         rm -rf $submnt
17377         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17378                 error "create remote directory failed"
17379         mkdir -p $submnt || error "create $submnt failed"
17380         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17381                 error "mount $submnt failed"
17382         stack_trap "umount $submnt" EXIT
17383
17384         cp $srcfile $dstfile
17385         fid=$($LFS path2fid $dstfile)
17386         path=$($LFS fid2path $submnt "$fid")
17387         [ "$path" = "$dstfile" ] ||
17388                 error "fid2path $submnt $fid failed ($path != $dstfile)"
17389 }
17390 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
17391
17392 # LU-1299 Executing or running ldd on a truncated executable does not
17393 # cause an out-of-memory condition.
17394 test_227() {
17395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17396         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17397
17398         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17399         chmod +x $MOUNT/date
17400
17401         $MOUNT/date > /dev/null
17402         ldd $MOUNT/date > /dev/null
17403         rm -f $MOUNT/date
17404 }
17405 run_test 227 "running truncated executable does not cause OOM"
17406
17407 # LU-1512 try to reuse idle OI blocks
17408 test_228a() {
17409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17410         remote_mds_nodsh && skip "remote MDS with nodsh"
17411         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17412
17413         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17414         local myDIR=$DIR/$tdir
17415
17416         mkdir -p $myDIR
17417         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17418         $LCTL set_param fail_loc=0x80001002
17419         createmany -o $myDIR/t- 10000
17420         $LCTL set_param fail_loc=0
17421         # The guard is current the largest FID holder
17422         touch $myDIR/guard
17423         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17424                     tr -d '[')
17425         local IDX=$(($SEQ % 64))
17426
17427         do_facet $SINGLEMDS sync
17428         # Make sure journal flushed.
17429         sleep 6
17430         local blk1=$(do_facet $SINGLEMDS \
17431                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17432                      grep Blockcount | awk '{print $4}')
17433
17434         # Remove old files, some OI blocks will become idle.
17435         unlinkmany $myDIR/t- 10000
17436         # Create new files, idle OI blocks should be reused.
17437         createmany -o $myDIR/t- 2000
17438         do_facet $SINGLEMDS sync
17439         # Make sure journal flushed.
17440         sleep 6
17441         local blk2=$(do_facet $SINGLEMDS \
17442                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17443                      grep Blockcount | awk '{print $4}')
17444
17445         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17446 }
17447 run_test 228a "try to reuse idle OI blocks"
17448
17449 test_228b() {
17450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17451         remote_mds_nodsh && skip "remote MDS with nodsh"
17452         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17453
17454         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17455         local myDIR=$DIR/$tdir
17456
17457         mkdir -p $myDIR
17458         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17459         $LCTL set_param fail_loc=0x80001002
17460         createmany -o $myDIR/t- 10000
17461         $LCTL set_param fail_loc=0
17462         # The guard is current the largest FID holder
17463         touch $myDIR/guard
17464         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17465                     tr -d '[')
17466         local IDX=$(($SEQ % 64))
17467
17468         do_facet $SINGLEMDS sync
17469         # Make sure journal flushed.
17470         sleep 6
17471         local blk1=$(do_facet $SINGLEMDS \
17472                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17473                      grep Blockcount | awk '{print $4}')
17474
17475         # Remove old files, some OI blocks will become idle.
17476         unlinkmany $myDIR/t- 10000
17477
17478         # stop the MDT
17479         stop $SINGLEMDS || error "Fail to stop MDT."
17480         # remount the MDT
17481         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17482
17483         df $MOUNT || error "Fail to df."
17484         # Create new files, idle OI blocks should be reused.
17485         createmany -o $myDIR/t- 2000
17486         do_facet $SINGLEMDS sync
17487         # Make sure journal flushed.
17488         sleep 6
17489         local blk2=$(do_facet $SINGLEMDS \
17490                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17491                      grep Blockcount | awk '{print $4}')
17492
17493         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17494 }
17495 run_test 228b "idle OI blocks can be reused after MDT restart"
17496
17497 #LU-1881
17498 test_228c() {
17499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17500         remote_mds_nodsh && skip "remote MDS with nodsh"
17501         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17502
17503         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17504         local myDIR=$DIR/$tdir
17505
17506         mkdir -p $myDIR
17507         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17508         $LCTL set_param fail_loc=0x80001002
17509         # 20000 files can guarantee there are index nodes in the OI file
17510         createmany -o $myDIR/t- 20000
17511         $LCTL set_param fail_loc=0
17512         # The guard is current the largest FID holder
17513         touch $myDIR/guard
17514         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17515                     tr -d '[')
17516         local IDX=$(($SEQ % 64))
17517
17518         do_facet $SINGLEMDS sync
17519         # Make sure journal flushed.
17520         sleep 6
17521         local blk1=$(do_facet $SINGLEMDS \
17522                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17523                      grep Blockcount | awk '{print $4}')
17524
17525         # Remove old files, some OI blocks will become idle.
17526         unlinkmany $myDIR/t- 20000
17527         rm -f $myDIR/guard
17528         # The OI file should become empty now
17529
17530         # Create new files, idle OI blocks should be reused.
17531         createmany -o $myDIR/t- 2000
17532         do_facet $SINGLEMDS sync
17533         # Make sure journal flushed.
17534         sleep 6
17535         local blk2=$(do_facet $SINGLEMDS \
17536                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17537                      grep Blockcount | awk '{print $4}')
17538
17539         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17540 }
17541 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17542
17543 test_229() { # LU-2482, LU-3448
17544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17545         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17546         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17547                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17548
17549         rm -f $DIR/$tfile
17550
17551         # Create a file with a released layout and stripe count 2.
17552         $MULTIOP $DIR/$tfile H2c ||
17553                 error "failed to create file with released layout"
17554
17555         $LFS getstripe -v $DIR/$tfile
17556
17557         local pattern=$($LFS getstripe -L $DIR/$tfile)
17558         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17559
17560         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17561                 error "getstripe"
17562         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17563         stat $DIR/$tfile || error "failed to stat released file"
17564
17565         chown $RUNAS_ID $DIR/$tfile ||
17566                 error "chown $RUNAS_ID $DIR/$tfile failed"
17567
17568         chgrp $RUNAS_ID $DIR/$tfile ||
17569                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17570
17571         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17572         rm $DIR/$tfile || error "failed to remove released file"
17573 }
17574 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17575
17576 test_230a() {
17577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17578         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17579         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17580                 skip "Need MDS version at least 2.11.52"
17581
17582         local MDTIDX=1
17583
17584         test_mkdir $DIR/$tdir
17585         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17586         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17587         [ $mdt_idx -ne 0 ] &&
17588                 error "create local directory on wrong MDT $mdt_idx"
17589
17590         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17591                         error "create remote directory failed"
17592         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17593         [ $mdt_idx -ne $MDTIDX ] &&
17594                 error "create remote directory on wrong MDT $mdt_idx"
17595
17596         createmany -o $DIR/$tdir/test_230/t- 10 ||
17597                 error "create files on remote directory failed"
17598         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17599         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17600         rm -r $DIR/$tdir || error "unlink remote directory failed"
17601 }
17602 run_test 230a "Create remote directory and files under the remote directory"
17603
17604 test_230b() {
17605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17606         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17607         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17608                 skip "Need MDS version at least 2.11.52"
17609
17610         local MDTIDX=1
17611         local mdt_index
17612         local i
17613         local file
17614         local pid
17615         local stripe_count
17616         local migrate_dir=$DIR/$tdir/migrate_dir
17617         local other_dir=$DIR/$tdir/other_dir
17618
17619         test_mkdir $DIR/$tdir
17620         test_mkdir -i0 -c1 $migrate_dir
17621         test_mkdir -i0 -c1 $other_dir
17622         for ((i=0; i<10; i++)); do
17623                 mkdir -p $migrate_dir/dir_${i}
17624                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17625                         error "create files under remote dir failed $i"
17626         done
17627
17628         cp /etc/passwd $migrate_dir/$tfile
17629         cp /etc/passwd $other_dir/$tfile
17630         chattr +SAD $migrate_dir
17631         chattr +SAD $migrate_dir/$tfile
17632
17633         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17634         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17635         local old_dir_mode=$(stat -c%f $migrate_dir)
17636         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17637
17638         mkdir -p $migrate_dir/dir_default_stripe2
17639         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17640         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17641
17642         mkdir -p $other_dir
17643         ln $migrate_dir/$tfile $other_dir/luna
17644         ln $migrate_dir/$tfile $migrate_dir/sofia
17645         ln $other_dir/$tfile $migrate_dir/david
17646         ln -s $migrate_dir/$tfile $other_dir/zachary
17647         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17648         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17649
17650         local len
17651         local lnktgt
17652
17653         # inline symlink
17654         for len in 58 59 60; do
17655                 lnktgt=$(str_repeat 'l' $len)
17656                 touch $migrate_dir/$lnktgt
17657                 ln -s $lnktgt $migrate_dir/${len}char_ln
17658         done
17659
17660         # PATH_MAX
17661         for len in 4094 4095; do
17662                 lnktgt=$(str_repeat 'l' $len)
17663                 ln -s $lnktgt $migrate_dir/${len}char_ln
17664         done
17665
17666         # NAME_MAX
17667         for len in 254 255; do
17668                 touch $migrate_dir/$(str_repeat 'l' $len)
17669         done
17670
17671         $LFS migrate -m $MDTIDX $migrate_dir ||
17672                 error "fails on migrating remote dir to MDT1"
17673
17674         echo "migratate to MDT1, then checking.."
17675         for ((i = 0; i < 10; i++)); do
17676                 for file in $(find $migrate_dir/dir_${i}); do
17677                         mdt_index=$($LFS getstripe -m $file)
17678                         # broken symlink getstripe will fail
17679                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17680                                 error "$file is not on MDT${MDTIDX}"
17681                 done
17682         done
17683
17684         # the multiple link file should still in MDT0
17685         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17686         [ $mdt_index == 0 ] ||
17687                 error "$file is not on MDT${MDTIDX}"
17688
17689         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17690         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17691                 error " expect $old_dir_flag get $new_dir_flag"
17692
17693         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17694         [ "$old_file_flag" = "$new_file_flag" ] ||
17695                 error " expect $old_file_flag get $new_file_flag"
17696
17697         local new_dir_mode=$(stat -c%f $migrate_dir)
17698         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17699                 error "expect mode $old_dir_mode get $new_dir_mode"
17700
17701         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17702         [ "$old_file_mode" = "$new_file_mode" ] ||
17703                 error "expect mode $old_file_mode get $new_file_mode"
17704
17705         diff /etc/passwd $migrate_dir/$tfile ||
17706                 error "$tfile different after migration"
17707
17708         diff /etc/passwd $other_dir/luna ||
17709                 error "luna different after migration"
17710
17711         diff /etc/passwd $migrate_dir/sofia ||
17712                 error "sofia different after migration"
17713
17714         diff /etc/passwd $migrate_dir/david ||
17715                 error "david different after migration"
17716
17717         diff /etc/passwd $other_dir/zachary ||
17718                 error "zachary different after migration"
17719
17720         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17721                 error "${tfile}_ln different after migration"
17722
17723         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17724                 error "${tfile}_ln_other different after migration"
17725
17726         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
17727         [ $stripe_count = 2 ] ||
17728                 error "dir strpe_count $d != 2 after migration."
17729
17730         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
17731         [ $stripe_count = 2 ] ||
17732                 error "file strpe_count $d != 2 after migration."
17733
17734         #migrate back to MDT0
17735         MDTIDX=0
17736
17737         $LFS migrate -m $MDTIDX $migrate_dir ||
17738                 error "fails on migrating remote dir to MDT0"
17739
17740         echo "migrate back to MDT0, checking.."
17741         for file in $(find $migrate_dir); do
17742                 mdt_index=$($LFS getstripe -m $file)
17743                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17744                         error "$file is not on MDT${MDTIDX}"
17745         done
17746
17747         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17748         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17749                 error " expect $old_dir_flag get $new_dir_flag"
17750
17751         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17752         [ "$old_file_flag" = "$new_file_flag" ] ||
17753                 error " expect $old_file_flag get $new_file_flag"
17754
17755         local new_dir_mode=$(stat -c%f $migrate_dir)
17756         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17757                 error "expect mode $old_dir_mode get $new_dir_mode"
17758
17759         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17760         [ "$old_file_mode" = "$new_file_mode" ] ||
17761                 error "expect mode $old_file_mode get $new_file_mode"
17762
17763         diff /etc/passwd ${migrate_dir}/$tfile ||
17764                 error "$tfile different after migration"
17765
17766         diff /etc/passwd ${other_dir}/luna ||
17767                 error "luna different after migration"
17768
17769         diff /etc/passwd ${migrate_dir}/sofia ||
17770                 error "sofia different after migration"
17771
17772         diff /etc/passwd ${other_dir}/zachary ||
17773                 error "zachary different after migration"
17774
17775         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17776                 error "${tfile}_ln different after migration"
17777
17778         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17779                 error "${tfile}_ln_other different after migration"
17780
17781         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
17782         [ $stripe_count = 2 ] ||
17783                 error "dir strpe_count $d != 2 after migration."
17784
17785         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
17786         [ $stripe_count = 2 ] ||
17787                 error "file strpe_count $d != 2 after migration."
17788
17789         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17790 }
17791 run_test 230b "migrate directory"
17792
17793 test_230c() {
17794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17795         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17796         remote_mds_nodsh && skip "remote MDS with nodsh"
17797         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17798                 skip "Need MDS version at least 2.11.52"
17799
17800         local MDTIDX=1
17801         local total=3
17802         local mdt_index
17803         local file
17804         local migrate_dir=$DIR/$tdir/migrate_dir
17805
17806         #If migrating directory fails in the middle, all entries of
17807         #the directory is still accessiable.
17808         test_mkdir $DIR/$tdir
17809         test_mkdir -i0 -c1 $migrate_dir
17810         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
17811         stat $migrate_dir
17812         createmany -o $migrate_dir/f $total ||
17813                 error "create files under ${migrate_dir} failed"
17814
17815         # fail after migrating top dir, and this will fail only once, so the
17816         # first sub file migration will fail (currently f3), others succeed.
17817         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
17818         do_facet mds1 lctl set_param fail_loc=0x1801
17819         local t=$(ls $migrate_dir | wc -l)
17820         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
17821                 error "migrate should fail"
17822         local u=$(ls $migrate_dir | wc -l)
17823         [ "$u" == "$t" ] || error "$u != $t during migration"
17824
17825         # add new dir/file should succeed
17826         mkdir $migrate_dir/dir ||
17827                 error "mkdir failed under migrating directory"
17828         touch $migrate_dir/file ||
17829                 error "create file failed under migrating directory"
17830
17831         # add file with existing name should fail
17832         for file in $migrate_dir/f*; do
17833                 stat $file > /dev/null || error "stat $file failed"
17834                 $OPENFILE -f O_CREAT:O_EXCL $file &&
17835                         error "open(O_CREAT|O_EXCL) $file should fail"
17836                 $MULTIOP $file m && error "create $file should fail"
17837                 touch $DIR/$tdir/remote_dir/$tfile ||
17838                         error "touch $tfile failed"
17839                 ln $DIR/$tdir/remote_dir/$tfile $file &&
17840                         error "link $file should fail"
17841                 mdt_index=$($LFS getstripe -m $file)
17842                 if [ $mdt_index == 0 ]; then
17843                         # file failed to migrate is not allowed to rename to
17844                         mv $DIR/$tdir/remote_dir/$tfile $file &&
17845                                 error "rename to $file should fail"
17846                 else
17847                         mv $DIR/$tdir/remote_dir/$tfile $file ||
17848                                 error "rename to $file failed"
17849                 fi
17850                 echo hello >> $file || error "write $file failed"
17851         done
17852
17853         # resume migration with different options should fail
17854         $LFS migrate -m 0 $migrate_dir &&
17855                 error "migrate -m 0 $migrate_dir should fail"
17856
17857         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
17858                 error "migrate -c 2 $migrate_dir should fail"
17859
17860         # resume migration should succeed
17861         $LFS migrate -m $MDTIDX $migrate_dir ||
17862                 error "migrate $migrate_dir failed"
17863
17864         echo "Finish migration, then checking.."
17865         for file in $(find $migrate_dir); do
17866                 mdt_index=$($LFS getstripe -m $file)
17867                 [ $mdt_index == $MDTIDX ] ||
17868                         error "$file is not on MDT${MDTIDX}"
17869         done
17870
17871         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17872 }
17873 run_test 230c "check directory accessiblity if migration failed"
17874
17875 test_230d() {
17876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17877         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17878         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17879                 skip "Need MDS version at least 2.11.52"
17880         # LU-11235
17881         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
17882
17883         local migrate_dir=$DIR/$tdir/migrate_dir
17884         local old_index
17885         local new_index
17886         local old_count
17887         local new_count
17888         local new_hash
17889         local mdt_index
17890         local i
17891         local j
17892
17893         old_index=$((RANDOM % MDSCOUNT))
17894         old_count=$((MDSCOUNT - old_index))
17895         new_index=$((RANDOM % MDSCOUNT))
17896         new_count=$((MDSCOUNT - new_index))
17897         new_hash=1 # for all_char
17898
17899         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
17900         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
17901
17902         test_mkdir $DIR/$tdir
17903         test_mkdir -i $old_index -c $old_count $migrate_dir
17904
17905         for ((i=0; i<100; i++)); do
17906                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
17907                 createmany -o $migrate_dir/dir_${i}/f 100 ||
17908                         error "create files under remote dir failed $i"
17909         done
17910
17911         echo -n "Migrate from MDT$old_index "
17912         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
17913         echo -n "to MDT$new_index"
17914         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
17915         echo
17916
17917         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
17918         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
17919                 error "migrate remote dir error"
17920
17921         echo "Finish migration, then checking.."
17922         for file in $(find $migrate_dir); do
17923                 mdt_index=$($LFS getstripe -m $file)
17924                 if [ $mdt_index -lt $new_index ] ||
17925                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
17926                         error "$file is on MDT$mdt_index"
17927                 fi
17928         done
17929
17930         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17931 }
17932 run_test 230d "check migrate big directory"
17933
17934 test_230e() {
17935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17936         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17937         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17938                 skip "Need MDS version at least 2.11.52"
17939
17940         local i
17941         local j
17942         local a_fid
17943         local b_fid
17944
17945         mkdir -p $DIR/$tdir
17946         mkdir $DIR/$tdir/migrate_dir
17947         mkdir $DIR/$tdir/other_dir
17948         touch $DIR/$tdir/migrate_dir/a
17949         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
17950         ls $DIR/$tdir/other_dir
17951
17952         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17953                 error "migrate dir fails"
17954
17955         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17956         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17957
17958         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17959         [ $mdt_index == 0 ] || error "a is not on MDT0"
17960
17961         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
17962                 error "migrate dir fails"
17963
17964         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
17965         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
17966
17967         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17968         [ $mdt_index == 1 ] || error "a is not on MDT1"
17969
17970         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
17971         [ $mdt_index == 1 ] || error "b is not on MDT1"
17972
17973         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17974         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
17975
17976         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
17977
17978         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17979 }
17980 run_test 230e "migrate mulitple local link files"
17981
17982 test_230f() {
17983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17984         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17985         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17986                 skip "Need MDS version at least 2.11.52"
17987
17988         local a_fid
17989         local ln_fid
17990
17991         mkdir -p $DIR/$tdir
17992         mkdir $DIR/$tdir/migrate_dir
17993         $LFS mkdir -i1 $DIR/$tdir/other_dir
17994         touch $DIR/$tdir/migrate_dir/a
17995         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
17996         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
17997         ls $DIR/$tdir/other_dir
17998
17999         # a should be migrated to MDT1, since no other links on MDT0
18000         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18001                 error "#1 migrate dir fails"
18002         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18003         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18004         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18005         [ $mdt_index == 1 ] || error "a is not on MDT1"
18006
18007         # a should stay on MDT1, because it is a mulitple link file
18008         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18009                 error "#2 migrate dir fails"
18010         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18011         [ $mdt_index == 1 ] || error "a is not on MDT1"
18012
18013         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18014                 error "#3 migrate dir fails"
18015
18016         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18017         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
18018         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
18019
18020         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
18021         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
18022
18023         # a should be migrated to MDT0, since no other links on MDT1
18024         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18025                 error "#4 migrate dir fails"
18026         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18027         [ $mdt_index == 0 ] || error "a is not on MDT0"
18028
18029         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18030 }
18031 run_test 230f "migrate mulitple remote link files"
18032
18033 test_230g() {
18034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18035         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18036         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18037                 skip "Need MDS version at least 2.11.52"
18038
18039         mkdir -p $DIR/$tdir/migrate_dir
18040
18041         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
18042                 error "migrating dir to non-exist MDT succeeds"
18043         true
18044 }
18045 run_test 230g "migrate dir to non-exist MDT"
18046
18047 test_230h() {
18048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18049         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18050         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18051                 skip "Need MDS version at least 2.11.52"
18052
18053         local mdt_index
18054
18055         mkdir -p $DIR/$tdir/migrate_dir
18056
18057         $LFS migrate -m1 $DIR &&
18058                 error "migrating mountpoint1 should fail"
18059
18060         $LFS migrate -m1 $DIR/$tdir/.. &&
18061                 error "migrating mountpoint2 should fail"
18062
18063         # same as mv
18064         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18065                 error "migrating $tdir/migrate_dir/.. should fail"
18066
18067         true
18068 }
18069 run_test 230h "migrate .. and root"
18070
18071 test_230i() {
18072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18073         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18074         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18075                 skip "Need MDS version at least 2.11.52"
18076
18077         mkdir -p $DIR/$tdir/migrate_dir
18078
18079         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18080                 error "migration fails with a tailing slash"
18081
18082         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18083                 error "migration fails with two tailing slashes"
18084 }
18085 run_test 230i "lfs migrate -m tolerates trailing slashes"
18086
18087 test_230j() {
18088         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18089         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18090                 skip "Need MDS version at least 2.11.52"
18091
18092         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18093         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18094                 error "create $tfile failed"
18095         cat /etc/passwd > $DIR/$tdir/$tfile
18096
18097         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18098
18099         cmp /etc/passwd $DIR/$tdir/$tfile ||
18100                 error "DoM file mismatch after migration"
18101 }
18102 run_test 230j "DoM file data not changed after dir migration"
18103
18104 test_230k() {
18105         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18106         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18107                 skip "Need MDS version at least 2.11.56"
18108
18109         local total=20
18110         local files_on_starting_mdt=0
18111
18112         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18113         $LFS getdirstripe $DIR/$tdir
18114         for i in $(seq $total); do
18115                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18116                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18117                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18118         done
18119
18120         echo "$files_on_starting_mdt files on MDT0"
18121
18122         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18123         $LFS getdirstripe $DIR/$tdir
18124
18125         files_on_starting_mdt=0
18126         for i in $(seq $total); do
18127                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18128                         error "file $tfile.$i mismatch after migration"
18129                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18130                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18131         done
18132
18133         echo "$files_on_starting_mdt files on MDT1 after migration"
18134         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18135
18136         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18137         $LFS getdirstripe $DIR/$tdir
18138
18139         files_on_starting_mdt=0
18140         for i in $(seq $total); do
18141                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18142                         error "file $tfile.$i mismatch after 2nd migration"
18143                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18144                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18145         done
18146
18147         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18148         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18149
18150         true
18151 }
18152 run_test 230k "file data not changed after dir migration"
18153
18154 test_230l() {
18155         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18156         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18157                 skip "Need MDS version at least 2.11.56"
18158
18159         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18160         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18161                 error "create files under remote dir failed $i"
18162         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18163 }
18164 run_test 230l "readdir between MDTs won't crash"
18165
18166 test_230m() {
18167         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18168         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18169                 skip "Need MDS version at least 2.11.56"
18170
18171         local MDTIDX=1
18172         local mig_dir=$DIR/$tdir/migrate_dir
18173         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18174         local shortstr="b"
18175         local val
18176
18177         echo "Creating files and dirs with xattrs"
18178         test_mkdir $DIR/$tdir
18179         test_mkdir -i0 -c1 $mig_dir
18180         mkdir $mig_dir/dir
18181         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18182                 error "cannot set xattr attr1 on dir"
18183         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18184                 error "cannot set xattr attr2 on dir"
18185         touch $mig_dir/dir/f0
18186         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18187                 error "cannot set xattr attr1 on file"
18188         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18189                 error "cannot set xattr attr2 on file"
18190         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18191         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18192         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18193         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18194         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18195         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18196         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18197         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18198         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18199
18200         echo "Migrating to MDT1"
18201         $LFS migrate -m $MDTIDX $mig_dir ||
18202                 error "fails on migrating dir to MDT1"
18203
18204         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18205         echo "Checking xattrs"
18206         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18207         [ "$val" = $longstr ] ||
18208                 error "expecting xattr1 $longstr on dir, found $val"
18209         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18210         [ "$val" = $shortstr ] ||
18211                 error "expecting xattr2 $shortstr on dir, found $val"
18212         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18213         [ "$val" = $longstr ] ||
18214                 error "expecting xattr1 $longstr on file, found $val"
18215         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18216         [ "$val" = $shortstr ] ||
18217                 error "expecting xattr2 $shortstr on file, found $val"
18218 }
18219 run_test 230m "xattrs not changed after dir migration"
18220
18221 test_230n() {
18222         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18223         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18224                 skip "Need MDS version at least 2.13.53"
18225
18226         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18227         cat /etc/hosts > $DIR/$tdir/$tfile
18228         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18229         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18230
18231         cmp /etc/hosts $DIR/$tdir/$tfile ||
18232                 error "File data mismatch after migration"
18233 }
18234 run_test 230n "Dir migration with mirrored file"
18235
18236 test_230o() {
18237         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18238         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18239                 skip "Need MDS version at least 2.13.52"
18240
18241         local mdts=$(comma_list $(mdts_nodes))
18242         local timeout=100
18243
18244         local restripe_status
18245         local delta
18246         local i
18247         local j
18248
18249         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18250
18251         # in case "crush" hash type is not set
18252         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18253
18254         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18255                            mdt.*MDT0000.enable_dir_restripe)
18256         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18257         stack_trap "do_nodes $mdts $LCTL set_param \
18258                     mdt.*.enable_dir_restripe=$restripe_status"
18259
18260         mkdir $DIR/$tdir
18261         createmany -m $DIR/$tdir/f 100 ||
18262                 error "create files under remote dir failed $i"
18263         createmany -d $DIR/$tdir/d 100 ||
18264                 error "create dirs under remote dir failed $i"
18265
18266         for i in $(seq 2 $MDSCOUNT); do
18267                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18268                 $LFS setdirstripe -c $i $DIR/$tdir ||
18269                         error "split -c $i $tdir failed"
18270                 wait_update $HOSTNAME \
18271                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18272                         error "dir split not finished"
18273                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18274                         awk '/migrate/ {sum += $2} END { print sum }')
18275                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18276                 # delta is around total_files/stripe_count
18277                 [ $delta -lt $((200 /(i - 1))) ] ||
18278                         error "$delta files migrated"
18279         done
18280 }
18281 run_test 230o "dir split"
18282
18283 test_230p() {
18284         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18285         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18286                 skip "Need MDS version at least 2.13.52"
18287
18288         local mdts=$(comma_list $(mdts_nodes))
18289         local timeout=100
18290
18291         local restripe_status
18292         local delta
18293         local i
18294         local j
18295
18296         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18297
18298         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18299
18300         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18301                            mdt.*MDT0000.enable_dir_restripe)
18302         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18303         stack_trap "do_nodes $mdts $LCTL set_param \
18304                     mdt.*.enable_dir_restripe=$restripe_status"
18305
18306         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18307         createmany -m $DIR/$tdir/f 100 ||
18308                 error "create files under remote dir failed $i"
18309         createmany -d $DIR/$tdir/d 100 ||
18310                 error "create dirs under remote dir failed $i"
18311
18312         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18313                 local mdt_hash="crush"
18314
18315                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18316                 $LFS setdirstripe -c $i $DIR/$tdir ||
18317                         error "split -c $i $tdir failed"
18318                 [ $i -eq 1 ] && mdt_hash="none"
18319                 wait_update $HOSTNAME \
18320                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18321                         error "dir merge not finished"
18322                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18323                         awk '/migrate/ {sum += $2} END { print sum }')
18324                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18325                 # delta is around total_files/stripe_count
18326                 [ $delta -lt $((200 / i)) ] ||
18327                         error "$delta files migrated"
18328         done
18329 }
18330 run_test 230p "dir merge"
18331
18332 test_230q() {
18333         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18334         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18335                 skip "Need MDS version at least 2.13.52"
18336
18337         local mdts=$(comma_list $(mdts_nodes))
18338         local saved_threshold=$(do_facet mds1 \
18339                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18340         local saved_delta=$(do_facet mds1 \
18341                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18342         local threshold=100
18343         local delta=2
18344         local total=0
18345         local stripe_count=0
18346         local stripe_index
18347         local nr_files
18348
18349         stack_trap "do_nodes $mdts $LCTL set_param \
18350                     mdt.*.dir_split_count=$saved_threshold"
18351         stack_trap "do_nodes $mdts $LCTL set_param \
18352                     mdt.*.dir_split_delta=$saved_delta"
18353         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18354         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18355         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18356         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18357         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18358         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18359
18360         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18361         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18362
18363         while [ $stripe_count -lt $MDSCOUNT ]; do
18364                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18365                         error "create sub files failed"
18366                 stat $DIR/$tdir > /dev/null
18367                 total=$((total + threshold * 3 / 2))
18368                 stripe_count=$((stripe_count + delta))
18369                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18370
18371                 wait_update $HOSTNAME \
18372                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18373                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18374
18375                 wait_update $HOSTNAME \
18376                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18377                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18378
18379                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18380                            grep -w $stripe_index | wc -l)
18381                 echo "$nr_files files on MDT$stripe_index after split"
18382                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18383                         error "$nr_files files on MDT$stripe_index after split"
18384
18385                 nr_files=$(ls $DIR/$tdir | wc -w)
18386                 [ $nr_files -eq $total ] ||
18387                         error "total sub files $nr_files != $total"
18388         done
18389 }
18390 run_test 230q "dir auto split"
18391
18392 test_230r() {
18393         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18394         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
18395         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
18396                 skip "Need MDS version at least 2.13.54"
18397
18398         # maximum amount of local locks:
18399         # parent striped dir - 2 locks
18400         # new stripe in parent to migrate to - 1 lock
18401         # source and target - 2 locks
18402         # Total 5 locks for regular file
18403         mkdir -p $DIR/$tdir
18404         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
18405         touch $DIR/$tdir/dir1/eee
18406
18407         # create 4 hardlink for 4 more locks
18408         # Total: 9 locks > RS_MAX_LOCKS (8)
18409         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
18410         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
18411         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
18412         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
18413         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
18414         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
18415         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
18416         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
18417
18418         cancel_lru_locks mdc
18419
18420         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
18421                 error "migrate dir fails"
18422
18423         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18424 }
18425 run_test 230r "migrate with too many local locks"
18426
18427 test_231a()
18428 {
18429         # For simplicity this test assumes that max_pages_per_rpc
18430         # is the same across all OSCs
18431         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18432         local bulk_size=$((max_pages * PAGE_SIZE))
18433         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18434                                        head -n 1)
18435
18436         mkdir -p $DIR/$tdir
18437         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18438                 error "failed to set stripe with -S ${brw_size}M option"
18439
18440         # clear the OSC stats
18441         $LCTL set_param osc.*.stats=0 &>/dev/null
18442         stop_writeback
18443
18444         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18445         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18446                 oflag=direct &>/dev/null || error "dd failed"
18447
18448         sync; sleep 1; sync # just to be safe
18449         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18450         if [ x$nrpcs != "x1" ]; then
18451                 $LCTL get_param osc.*.stats
18452                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18453         fi
18454
18455         start_writeback
18456         # Drop the OSC cache, otherwise we will read from it
18457         cancel_lru_locks osc
18458
18459         # clear the OSC stats
18460         $LCTL set_param osc.*.stats=0 &>/dev/null
18461
18462         # Client reads $bulk_size.
18463         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18464                 iflag=direct &>/dev/null || error "dd failed"
18465
18466         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18467         if [ x$nrpcs != "x1" ]; then
18468                 $LCTL get_param osc.*.stats
18469                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18470         fi
18471 }
18472 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18473
18474 test_231b() {
18475         mkdir -p $DIR/$tdir
18476         local i
18477         for i in {0..1023}; do
18478                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18479                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18480                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18481         done
18482         sync
18483 }
18484 run_test 231b "must not assert on fully utilized OST request buffer"
18485
18486 test_232a() {
18487         mkdir -p $DIR/$tdir
18488         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18489
18490         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18491         do_facet ost1 $LCTL set_param fail_loc=0x31c
18492
18493         # ignore dd failure
18494         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
18495
18496         do_facet ost1 $LCTL set_param fail_loc=0
18497         umount_client $MOUNT || error "umount failed"
18498         mount_client $MOUNT || error "mount failed"
18499         stop ost1 || error "cannot stop ost1"
18500         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18501 }
18502 run_test 232a "failed lock should not block umount"
18503
18504 test_232b() {
18505         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
18506                 skip "Need MDS version at least 2.10.58"
18507
18508         mkdir -p $DIR/$tdir
18509         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18510         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
18511         sync
18512         cancel_lru_locks osc
18513
18514         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18515         do_facet ost1 $LCTL set_param fail_loc=0x31c
18516
18517         # ignore failure
18518         $LFS data_version $DIR/$tdir/$tfile || true
18519
18520         do_facet ost1 $LCTL set_param fail_loc=0
18521         umount_client $MOUNT || error "umount failed"
18522         mount_client $MOUNT || error "mount failed"
18523         stop ost1 || error "cannot stop ost1"
18524         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18525 }
18526 run_test 232b "failed data version lock should not block umount"
18527
18528 test_233a() {
18529         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
18530                 skip "Need MDS version at least 2.3.64"
18531         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18532
18533         local fid=$($LFS path2fid $MOUNT)
18534
18535         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18536                 error "cannot access $MOUNT using its FID '$fid'"
18537 }
18538 run_test 233a "checking that OBF of the FS root succeeds"
18539
18540 test_233b() {
18541         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
18542                 skip "Need MDS version at least 2.5.90"
18543         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18544
18545         local fid=$($LFS path2fid $MOUNT/.lustre)
18546
18547         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18548                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
18549
18550         fid=$($LFS path2fid $MOUNT/.lustre/fid)
18551         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18552                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
18553 }
18554 run_test 233b "checking that OBF of the FS .lustre succeeds"
18555
18556 test_234() {
18557         local p="$TMP/sanityN-$TESTNAME.parameters"
18558         save_lustre_params client "llite.*.xattr_cache" > $p
18559         lctl set_param llite.*.xattr_cache 1 ||
18560                 skip_env "xattr cache is not supported"
18561
18562         mkdir -p $DIR/$tdir || error "mkdir failed"
18563         touch $DIR/$tdir/$tfile || error "touch failed"
18564         # OBD_FAIL_LLITE_XATTR_ENOMEM
18565         $LCTL set_param fail_loc=0x1405
18566         getfattr -n user.attr $DIR/$tdir/$tfile &&
18567                 error "getfattr should have failed with ENOMEM"
18568         $LCTL set_param fail_loc=0x0
18569         rm -rf $DIR/$tdir
18570
18571         restore_lustre_params < $p
18572         rm -f $p
18573 }
18574 run_test 234 "xattr cache should not crash on ENOMEM"
18575
18576 test_235() {
18577         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
18578                 skip "Need MDS version at least 2.4.52"
18579
18580         flock_deadlock $DIR/$tfile
18581         local RC=$?
18582         case $RC in
18583                 0)
18584                 ;;
18585                 124) error "process hangs on a deadlock"
18586                 ;;
18587                 *) error "error executing flock_deadlock $DIR/$tfile"
18588                 ;;
18589         esac
18590 }
18591 run_test 235 "LU-1715: flock deadlock detection does not work properly"
18592
18593 #LU-2935
18594 test_236() {
18595         check_swap_layouts_support
18596
18597         local ref1=/etc/passwd
18598         local ref2=/etc/group
18599         local file1=$DIR/$tdir/f1
18600         local file2=$DIR/$tdir/f2
18601
18602         test_mkdir -c1 $DIR/$tdir
18603         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
18604         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
18605         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
18606         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
18607         local fd=$(free_fd)
18608         local cmd="exec $fd<>$file2"
18609         eval $cmd
18610         rm $file2
18611         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
18612                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
18613         cmd="exec $fd>&-"
18614         eval $cmd
18615         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18616
18617         #cleanup
18618         rm -rf $DIR/$tdir
18619 }
18620 run_test 236 "Layout swap on open unlinked file"
18621
18622 # LU-4659 linkea consistency
18623 test_238() {
18624         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18625                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18626                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18627                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18628
18629         touch $DIR/$tfile
18630         ln $DIR/$tfile $DIR/$tfile.lnk
18631         touch $DIR/$tfile.new
18632         mv $DIR/$tfile.new $DIR/$tfile
18633         local fid1=$($LFS path2fid $DIR/$tfile)
18634         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
18635         local path1=$($LFS fid2path $FSNAME "$fid1")
18636         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
18637         local path2=$($LFS fid2path $FSNAME "$fid2")
18638         [ $tfile.lnk == $path2 ] ||
18639                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
18640         rm -f $DIR/$tfile*
18641 }
18642 run_test 238 "Verify linkea consistency"
18643
18644 test_239A() { # was test_239
18645         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
18646                 skip "Need MDS version at least 2.5.60"
18647
18648         local list=$(comma_list $(mdts_nodes))
18649
18650         mkdir -p $DIR/$tdir
18651         createmany -o $DIR/$tdir/f- 5000
18652         unlinkmany $DIR/$tdir/f- 5000
18653         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
18654                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
18655         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
18656                         osp.*MDT*.sync_in_flight" | calc_sum)
18657         [ "$changes" -eq 0 ] || error "$changes not synced"
18658 }
18659 run_test 239A "osp_sync test"
18660
18661 test_239a() { #LU-5297
18662         remote_mds_nodsh && skip "remote MDS with nodsh"
18663
18664         touch $DIR/$tfile
18665         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
18666         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
18667         chgrp $RUNAS_GID $DIR/$tfile
18668         wait_delete_completed
18669 }
18670 run_test 239a "process invalid osp sync record correctly"
18671
18672 test_239b() { #LU-5297
18673         remote_mds_nodsh && skip "remote MDS with nodsh"
18674
18675         touch $DIR/$tfile1
18676         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
18677         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
18678         chgrp $RUNAS_GID $DIR/$tfile1
18679         wait_delete_completed
18680         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18681         touch $DIR/$tfile2
18682         chgrp $RUNAS_GID $DIR/$tfile2
18683         wait_delete_completed
18684 }
18685 run_test 239b "process osp sync record with ENOMEM error correctly"
18686
18687 test_240() {
18688         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18689         remote_mds_nodsh && skip "remote MDS with nodsh"
18690
18691         mkdir -p $DIR/$tdir
18692
18693         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
18694                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
18695         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
18696                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
18697
18698         umount_client $MOUNT || error "umount failed"
18699         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
18700         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
18701         mount_client $MOUNT || error "failed to mount client"
18702
18703         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
18704         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
18705 }
18706 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
18707
18708 test_241_bio() {
18709         local count=$1
18710         local bsize=$2
18711
18712         for LOOP in $(seq $count); do
18713                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
18714                 cancel_lru_locks $OSC || true
18715         done
18716 }
18717
18718 test_241_dio() {
18719         local count=$1
18720         local bsize=$2
18721
18722         for LOOP in $(seq $1); do
18723                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
18724                         2>/dev/null
18725         done
18726 }
18727
18728 test_241a() { # was test_241
18729         local bsize=$PAGE_SIZE
18730
18731         (( bsize < 40960 )) && bsize=40960
18732         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18733         ls -la $DIR/$tfile
18734         cancel_lru_locks $OSC
18735         test_241_bio 1000 $bsize &
18736         PID=$!
18737         test_241_dio 1000 $bsize
18738         wait $PID
18739 }
18740 run_test 241a "bio vs dio"
18741
18742 test_241b() {
18743         local bsize=$PAGE_SIZE
18744
18745         (( bsize < 40960 )) && bsize=40960
18746         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18747         ls -la $DIR/$tfile
18748         test_241_dio 1000 $bsize &
18749         PID=$!
18750         test_241_dio 1000 $bsize
18751         wait $PID
18752 }
18753 run_test 241b "dio vs dio"
18754
18755 test_242() {
18756         remote_mds_nodsh && skip "remote MDS with nodsh"
18757
18758         mkdir -p $DIR/$tdir
18759         touch $DIR/$tdir/$tfile
18760
18761         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
18762         do_facet mds1 lctl set_param fail_loc=0x105
18763         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
18764
18765         do_facet mds1 lctl set_param fail_loc=0
18766         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
18767 }
18768 run_test 242 "mdt_readpage failure should not cause directory unreadable"
18769
18770 test_243()
18771 {
18772         test_mkdir $DIR/$tdir
18773         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
18774 }
18775 run_test 243 "various group lock tests"
18776
18777 test_244a()
18778 {
18779         test_mkdir $DIR/$tdir
18780         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
18781         sendfile_grouplock $DIR/$tdir/$tfile || \
18782                 error "sendfile+grouplock failed"
18783         rm -rf $DIR/$tdir
18784 }
18785 run_test 244a "sendfile with group lock tests"
18786
18787 test_244b()
18788 {
18789         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18790
18791         local threads=50
18792         local size=$((1024*1024))
18793
18794         test_mkdir $DIR/$tdir
18795         for i in $(seq 1 $threads); do
18796                 local file=$DIR/$tdir/file_$((i / 10))
18797                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
18798                 local pids[$i]=$!
18799         done
18800         for i in $(seq 1 $threads); do
18801                 wait ${pids[$i]}
18802         done
18803 }
18804 run_test 244b "multi-threaded write with group lock"
18805
18806 test_245() {
18807         local flagname="multi_mod_rpcs"
18808         local connect_data_name="max_mod_rpcs"
18809         local out
18810
18811         # check if multiple modify RPCs flag is set
18812         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
18813                 grep "connect_flags:")
18814         echo "$out"
18815
18816         echo "$out" | grep -qw $flagname
18817         if [ $? -ne 0 ]; then
18818                 echo "connect flag $flagname is not set"
18819                 return
18820         fi
18821
18822         # check if multiple modify RPCs data is set
18823         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
18824         echo "$out"
18825
18826         echo "$out" | grep -qw $connect_data_name ||
18827                 error "import should have connect data $connect_data_name"
18828 }
18829 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
18830
18831 cleanup_247() {
18832         local submount=$1
18833
18834         trap 0
18835         umount_client $submount
18836         rmdir $submount
18837 }
18838
18839 test_247a() {
18840         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18841                 grep -q subtree ||
18842                 skip_env "Fileset feature is not supported"
18843
18844         local submount=${MOUNT}_$tdir
18845
18846         mkdir $MOUNT/$tdir
18847         mkdir -p $submount || error "mkdir $submount failed"
18848         FILESET="$FILESET/$tdir" mount_client $submount ||
18849                 error "mount $submount failed"
18850         trap "cleanup_247 $submount" EXIT
18851         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
18852         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
18853                 error "read $MOUNT/$tdir/$tfile failed"
18854         cleanup_247 $submount
18855 }
18856 run_test 247a "mount subdir as fileset"
18857
18858 test_247b() {
18859         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18860                 skip_env "Fileset feature is not supported"
18861
18862         local submount=${MOUNT}_$tdir
18863
18864         rm -rf $MOUNT/$tdir
18865         mkdir -p $submount || error "mkdir $submount failed"
18866         SKIP_FILESET=1
18867         FILESET="$FILESET/$tdir" mount_client $submount &&
18868                 error "mount $submount should fail"
18869         rmdir $submount
18870 }
18871 run_test 247b "mount subdir that dose not exist"
18872
18873 test_247c() {
18874         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18875                 skip_env "Fileset feature is not supported"
18876
18877         local submount=${MOUNT}_$tdir
18878
18879         mkdir -p $MOUNT/$tdir/dir1
18880         mkdir -p $submount || error "mkdir $submount failed"
18881         trap "cleanup_247 $submount" EXIT
18882         FILESET="$FILESET/$tdir" mount_client $submount ||
18883                 error "mount $submount failed"
18884         local fid=$($LFS path2fid $MOUNT/)
18885         $LFS fid2path $submount $fid && error "fid2path should fail"
18886         cleanup_247 $submount
18887 }
18888 run_test 247c "running fid2path outside subdirectory root"
18889
18890 test_247d() {
18891         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18892                 skip "Fileset feature is not supported"
18893
18894         local submount=${MOUNT}_$tdir
18895
18896         mkdir -p $MOUNT/$tdir/dir1
18897         mkdir -p $submount || error "mkdir $submount failed"
18898         FILESET="$FILESET/$tdir" mount_client $submount ||
18899                 error "mount $submount failed"
18900         trap "cleanup_247 $submount" EXIT
18901
18902         local td=$submount/dir1
18903         local fid=$($LFS path2fid $td)
18904         [ -z "$fid" ] && error "path2fid unable to get $td FID"
18905
18906         # check that we get the same pathname back
18907         local rootpath
18908         local found
18909         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
18910                 echo "$rootpath $fid"
18911                 found=$($LFS fid2path $rootpath "$fid")
18912                 [ -n "found" ] || error "fid2path should succeed"
18913                 [ "$found" == "$td" ] || error "fid2path $found != $td"
18914         done
18915         # check wrong root path format
18916         rootpath=$submount"_wrong"
18917         found=$($LFS fid2path $rootpath "$fid")
18918         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
18919
18920         cleanup_247 $submount
18921 }
18922 run_test 247d "running fid2path inside subdirectory root"
18923
18924 # LU-8037
18925 test_247e() {
18926         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18927                 grep -q subtree ||
18928                 skip "Fileset feature is not supported"
18929
18930         local submount=${MOUNT}_$tdir
18931
18932         mkdir $MOUNT/$tdir
18933         mkdir -p $submount || error "mkdir $submount failed"
18934         FILESET="$FILESET/.." mount_client $submount &&
18935                 error "mount $submount should fail"
18936         rmdir $submount
18937 }
18938 run_test 247e "mount .. as fileset"
18939
18940 test_247f() {
18941         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18942         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18943                 skip "Need at least version 2.13.52"
18944         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18945                 grep -q subtree ||
18946                 skip "Fileset feature is not supported"
18947
18948         mkdir $DIR/$tdir || error "mkdir $tdir failed"
18949         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
18950                 error "mkdir remote failed"
18951         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
18952         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
18953                 error "mkdir striped failed"
18954         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
18955
18956         local submount=${MOUNT}_$tdir
18957
18958         mkdir -p $submount || error "mkdir $submount failed"
18959
18960         local dir
18961         local fileset=$FILESET
18962
18963         for dir in $tdir/remote $tdir/remote/subdir \
18964                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
18965                 FILESET="$fileset/$dir" mount_client $submount ||
18966                         error "mount $dir failed"
18967                 umount_client $submount
18968         done
18969 }
18970 run_test 247f "mount striped or remote directory as fileset"
18971
18972 test_248a() {
18973         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
18974         [ -z "$fast_read_sav" ] && skip "no fast read support"
18975
18976         # create a large file for fast read verification
18977         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
18978
18979         # make sure the file is created correctly
18980         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
18981                 { rm -f $DIR/$tfile; skip "file creation error"; }
18982
18983         echo "Test 1: verify that fast read is 4 times faster on cache read"
18984
18985         # small read with fast read enabled
18986         $LCTL set_param -n llite.*.fast_read=1
18987         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18988                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18989                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18990         # small read with fast read disabled
18991         $LCTL set_param -n llite.*.fast_read=0
18992         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18993                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18994                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18995
18996         # verify that fast read is 4 times faster for cache read
18997         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
18998                 error_not_in_vm "fast read was not 4 times faster: " \
18999                            "$t_fast vs $t_slow"
19000
19001         echo "Test 2: verify the performance between big and small read"
19002         $LCTL set_param -n llite.*.fast_read=1
19003
19004         # 1k non-cache read
19005         cancel_lru_locks osc
19006         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19007                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19008                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19009
19010         # 1M non-cache read
19011         cancel_lru_locks osc
19012         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19013                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19014                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19015
19016         # verify that big IO is not 4 times faster than small IO
19017         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
19018                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
19019
19020         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
19021         rm -f $DIR/$tfile
19022 }
19023 run_test 248a "fast read verification"
19024
19025 test_248b() {
19026         # Default short_io_bytes=16384, try both smaller and larger sizes.
19027         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
19028         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
19029         echo "bs=53248 count=113 normal buffered write"
19030         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
19031                 error "dd of initial data file failed"
19032         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
19033
19034         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
19035         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
19036                 error "dd with sync normal writes failed"
19037         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
19038
19039         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
19040         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
19041                 error "dd with sync small writes failed"
19042         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
19043
19044         cancel_lru_locks osc
19045
19046         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
19047         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
19048         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
19049         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
19050                 iflag=direct || error "dd with O_DIRECT small read failed"
19051         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
19052         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
19053                 error "compare $TMP/$tfile.1 failed"
19054
19055         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
19056         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
19057
19058         # just to see what the maximum tunable value is, and test parsing
19059         echo "test invalid parameter 2MB"
19060         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
19061                 error "too-large short_io_bytes allowed"
19062         echo "test maximum parameter 512KB"
19063         # if we can set a larger short_io_bytes, run test regardless of version
19064         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
19065                 # older clients may not allow setting it this large, that's OK
19066                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
19067                         skip "Need at least client version 2.13.50"
19068                 error "medium short_io_bytes failed"
19069         fi
19070         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19071         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
19072
19073         echo "test large parameter 64KB"
19074         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
19075         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19076
19077         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
19078         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
19079                 error "dd with sync large writes failed"
19080         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19081
19082         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19083         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19084         num=$((113 * 4096 / PAGE_SIZE))
19085         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19086         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19087                 error "dd with O_DIRECT large writes failed"
19088         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19089                 error "compare $DIR/$tfile.3 failed"
19090
19091         cancel_lru_locks osc
19092
19093         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19094         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19095                 error "dd with O_DIRECT large read failed"
19096         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19097                 error "compare $TMP/$tfile.2 failed"
19098
19099         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19100         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19101                 error "dd with O_DIRECT large read failed"
19102         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19103                 error "compare $TMP/$tfile.3 failed"
19104 }
19105 run_test 248b "test short_io read and write for both small and large sizes"
19106
19107 test_249() { # LU-7890
19108         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19109                 skip "Need at least version 2.8.54"
19110
19111         rm -f $DIR/$tfile
19112         $LFS setstripe -c 1 $DIR/$tfile
19113         # Offset 2T == 4k * 512M
19114         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19115                 error "dd to 2T offset failed"
19116 }
19117 run_test 249 "Write above 2T file size"
19118
19119 test_250() {
19120         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19121          && skip "no 16TB file size limit on ZFS"
19122
19123         $LFS setstripe -c 1 $DIR/$tfile
19124         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19125         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19126         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19127         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19128                 conv=notrunc,fsync && error "append succeeded"
19129         return 0
19130 }
19131 run_test 250 "Write above 16T limit"
19132
19133 test_251() {
19134         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19135
19136         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19137         #Skip once - writing the first stripe will succeed
19138         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19139         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19140                 error "short write happened"
19141
19142         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19143         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19144                 error "short read happened"
19145
19146         rm -f $DIR/$tfile
19147 }
19148 run_test 251 "Handling short read and write correctly"
19149
19150 test_252() {
19151         remote_mds_nodsh && skip "remote MDS with nodsh"
19152         remote_ost_nodsh && skip "remote OST with nodsh"
19153         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19154                 skip_env "ldiskfs only test"
19155         fi
19156
19157         local tgt
19158         local dev
19159         local out
19160         local uuid
19161         local num
19162         local gen
19163
19164         # check lr_reader on OST0000
19165         tgt=ost1
19166         dev=$(facet_device $tgt)
19167         out=$(do_facet $tgt $LR_READER $dev)
19168         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19169         echo "$out"
19170         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19171         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19172                 error "Invalid uuid returned by $LR_READER on target $tgt"
19173         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19174
19175         # check lr_reader -c on MDT0000
19176         tgt=mds1
19177         dev=$(facet_device $tgt)
19178         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19179                 skip "$LR_READER does not support additional options"
19180         fi
19181         out=$(do_facet $tgt $LR_READER -c $dev)
19182         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19183         echo "$out"
19184         num=$(echo "$out" | grep -c "mdtlov")
19185         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19186                 error "Invalid number of mdtlov clients returned by $LR_READER"
19187         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19188
19189         # check lr_reader -cr on MDT0000
19190         out=$(do_facet $tgt $LR_READER -cr $dev)
19191         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19192         echo "$out"
19193         echo "$out" | grep -q "^reply_data:$" ||
19194                 error "$LR_READER should have returned 'reply_data' section"
19195         num=$(echo "$out" | grep -c "client_generation")
19196         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19197 }
19198 run_test 252 "check lr_reader tool"
19199
19200 test_253() {
19201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19202         remote_mds_nodsh && skip "remote MDS with nodsh"
19203         remote_mgs_nodsh && skip "remote MGS with nodsh"
19204
19205         local ostidx=0
19206         local rc=0
19207         local ost_name=$(ostname_from_index $ostidx)
19208
19209         # on the mdt's osc
19210         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19211         do_facet $SINGLEMDS $LCTL get_param -n \
19212                 osp.$mdtosc_proc1.reserved_mb_high ||
19213                 skip  "remote MDS does not support reserved_mb_high"
19214
19215         rm -rf $DIR/$tdir
19216         wait_mds_ost_sync
19217         wait_delete_completed
19218         mkdir $DIR/$tdir
19219
19220         pool_add $TESTNAME || error "Pool creation failed"
19221         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19222
19223         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19224                 error "Setstripe failed"
19225
19226         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19227
19228         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19229                     grep "watermarks")
19230         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19231
19232         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19233                         osp.$mdtosc_proc1.prealloc_status)
19234         echo "prealloc_status $oa_status"
19235
19236         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19237                 error "File creation should fail"
19238
19239         #object allocation was stopped, but we still able to append files
19240         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19241                 oflag=append || error "Append failed"
19242
19243         rm -f $DIR/$tdir/$tfile.0
19244
19245         # For this test, we want to delete the files we created to go out of
19246         # space but leave the watermark, so we remain nearly out of space
19247         ost_watermarks_enospc_delete_files $tfile $ostidx
19248
19249         wait_delete_completed
19250
19251         sleep_maxage
19252
19253         for i in $(seq 10 12); do
19254                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19255                         2>/dev/null || error "File creation failed after rm"
19256         done
19257
19258         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19259                         osp.$mdtosc_proc1.prealloc_status)
19260         echo "prealloc_status $oa_status"
19261
19262         if (( oa_status != 0 )); then
19263                 error "Object allocation still disable after rm"
19264         fi
19265 }
19266 run_test 253 "Check object allocation limit"
19267
19268 test_254() {
19269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19270         remote_mds_nodsh && skip "remote MDS with nodsh"
19271         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19272                 skip "MDS does not support changelog_size"
19273
19274         local cl_user
19275         local MDT0=$(facet_svc $SINGLEMDS)
19276
19277         changelog_register || error "changelog_register failed"
19278
19279         changelog_clear 0 || error "changelog_clear failed"
19280
19281         local size1=$(do_facet $SINGLEMDS \
19282                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19283         echo "Changelog size $size1"
19284
19285         rm -rf $DIR/$tdir
19286         $LFS mkdir -i 0 $DIR/$tdir
19287         # change something
19288         mkdir -p $DIR/$tdir/pics/2008/zachy
19289         touch $DIR/$tdir/pics/2008/zachy/timestamp
19290         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19291         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19292         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19293         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19294         rm $DIR/$tdir/pics/desktop.jpg
19295
19296         local size2=$(do_facet $SINGLEMDS \
19297                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19298         echo "Changelog size after work $size2"
19299
19300         (( $size2 > $size1 )) ||
19301                 error "new Changelog size=$size2 less than old size=$size1"
19302 }
19303 run_test 254 "Check changelog size"
19304
19305 ladvise_no_type()
19306 {
19307         local type=$1
19308         local file=$2
19309
19310         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19311                 awk -F: '{print $2}' | grep $type > /dev/null
19312         if [ $? -ne 0 ]; then
19313                 return 0
19314         fi
19315         return 1
19316 }
19317
19318 ladvise_no_ioctl()
19319 {
19320         local file=$1
19321
19322         lfs ladvise -a willread $file > /dev/null 2>&1
19323         if [ $? -eq 0 ]; then
19324                 return 1
19325         fi
19326
19327         lfs ladvise -a willread $file 2>&1 |
19328                 grep "Inappropriate ioctl for device" > /dev/null
19329         if [ $? -eq 0 ]; then
19330                 return 0
19331         fi
19332         return 1
19333 }
19334
19335 percent() {
19336         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19337 }
19338
19339 # run a random read IO workload
19340 # usage: random_read_iops <filename> <filesize> <iosize>
19341 random_read_iops() {
19342         local file=$1
19343         local fsize=$2
19344         local iosize=${3:-4096}
19345
19346         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19347                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19348 }
19349
19350 drop_file_oss_cache() {
19351         local file="$1"
19352         local nodes="$2"
19353
19354         $LFS ladvise -a dontneed $file 2>/dev/null ||
19355                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19356 }
19357
19358 ladvise_willread_performance()
19359 {
19360         local repeat=10
19361         local average_origin=0
19362         local average_cache=0
19363         local average_ladvise=0
19364
19365         for ((i = 1; i <= $repeat; i++)); do
19366                 echo "Iter $i/$repeat: reading without willread hint"
19367                 cancel_lru_locks osc
19368                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19369                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19370                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19371                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19372
19373                 cancel_lru_locks osc
19374                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19375                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19376                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19377
19378                 cancel_lru_locks osc
19379                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19380                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19381                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19382                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19383                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19384         done
19385         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19386         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19387         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19388
19389         speedup_cache=$(percent $average_cache $average_origin)
19390         speedup_ladvise=$(percent $average_ladvise $average_origin)
19391
19392         echo "Average uncached read: $average_origin"
19393         echo "Average speedup with OSS cached read: " \
19394                 "$average_cache = +$speedup_cache%"
19395         echo "Average speedup with ladvise willread: " \
19396                 "$average_ladvise = +$speedup_ladvise%"
19397
19398         local lowest_speedup=20
19399         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19400                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19401                         "got $average_cache%. Skipping ladvise willread check."
19402                 return 0
19403         fi
19404
19405         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19406         # it is still good to run until then to exercise 'ladvise willread'
19407         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19408                 [ "$ost1_FSTYPE" = "zfs" ] &&
19409                 echo "osd-zfs does not support dontneed or drop_caches" &&
19410                 return 0
19411
19412         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19413         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
19414                 error_not_in_vm "Speedup with willread is less than " \
19415                         "$lowest_speedup%, got $average_ladvise%"
19416 }
19417
19418 test_255a() {
19419         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19420                 skip "lustre < 2.8.54 does not support ladvise "
19421         remote_ost_nodsh && skip "remote OST with nodsh"
19422
19423         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19424
19425         ladvise_no_type willread $DIR/$tfile &&
19426                 skip "willread ladvise is not supported"
19427
19428         ladvise_no_ioctl $DIR/$tfile &&
19429                 skip "ladvise ioctl is not supported"
19430
19431         local size_mb=100
19432         local size=$((size_mb * 1048576))
19433         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19434                 error "dd to $DIR/$tfile failed"
19435
19436         lfs ladvise -a willread $DIR/$tfile ||
19437                 error "Ladvise failed with no range argument"
19438
19439         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19440                 error "Ladvise failed with no -l or -e argument"
19441
19442         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19443                 error "Ladvise failed with only -e argument"
19444
19445         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19446                 error "Ladvise failed with only -l argument"
19447
19448         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19449                 error "End offset should not be smaller than start offset"
19450
19451         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19452                 error "End offset should not be equal to start offset"
19453
19454         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19455                 error "Ladvise failed with overflowing -s argument"
19456
19457         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19458                 error "Ladvise failed with overflowing -e argument"
19459
19460         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19461                 error "Ladvise failed with overflowing -l argument"
19462
19463         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19464                 error "Ladvise succeeded with conflicting -l and -e arguments"
19465
19466         echo "Synchronous ladvise should wait"
19467         local delay=4
19468 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19469         do_nodes $(comma_list $(osts_nodes)) \
19470                 $LCTL set_param fail_val=$delay fail_loc=0x237
19471
19472         local start_ts=$SECONDS
19473         lfs ladvise -a willread $DIR/$tfile ||
19474                 error "Ladvise failed with no range argument"
19475         local end_ts=$SECONDS
19476         local inteval_ts=$((end_ts - start_ts))
19477
19478         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19479                 error "Synchronous advice didn't wait reply"
19480         fi
19481
19482         echo "Asynchronous ladvise shouldn't wait"
19483         local start_ts=$SECONDS
19484         lfs ladvise -a willread -b $DIR/$tfile ||
19485                 error "Ladvise failed with no range argument"
19486         local end_ts=$SECONDS
19487         local inteval_ts=$((end_ts - start_ts))
19488
19489         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19490                 error "Asynchronous advice blocked"
19491         fi
19492
19493         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
19494         ladvise_willread_performance
19495 }
19496 run_test 255a "check 'lfs ladvise -a willread'"
19497
19498 facet_meminfo() {
19499         local facet=$1
19500         local info=$2
19501
19502         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
19503 }
19504
19505 test_255b() {
19506         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19507                 skip "lustre < 2.8.54 does not support ladvise "
19508         remote_ost_nodsh && skip "remote OST with nodsh"
19509
19510         lfs setstripe -c 1 -i 0 $DIR/$tfile
19511
19512         ladvise_no_type dontneed $DIR/$tfile &&
19513                 skip "dontneed ladvise is not supported"
19514
19515         ladvise_no_ioctl $DIR/$tfile &&
19516                 skip "ladvise ioctl is not supported"
19517
19518         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19519                 [ "$ost1_FSTYPE" = "zfs" ] &&
19520                 skip "zfs-osd does not support 'ladvise dontneed'"
19521
19522         local size_mb=100
19523         local size=$((size_mb * 1048576))
19524         # In order to prevent disturbance of other processes, only check 3/4
19525         # of the memory usage
19526         local kibibytes=$((size_mb * 1024 * 3 / 4))
19527
19528         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19529                 error "dd to $DIR/$tfile failed"
19530
19531         #force write to complete before dropping OST cache & checking memory
19532         sync
19533
19534         local total=$(facet_meminfo ost1 MemTotal)
19535         echo "Total memory: $total KiB"
19536
19537         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
19538         local before_read=$(facet_meminfo ost1 Cached)
19539         echo "Cache used before read: $before_read KiB"
19540
19541         lfs ladvise -a willread $DIR/$tfile ||
19542                 error "Ladvise willread failed"
19543         local after_read=$(facet_meminfo ost1 Cached)
19544         echo "Cache used after read: $after_read KiB"
19545
19546         lfs ladvise -a dontneed $DIR/$tfile ||
19547                 error "Ladvise dontneed again failed"
19548         local no_read=$(facet_meminfo ost1 Cached)
19549         echo "Cache used after dontneed ladvise: $no_read KiB"
19550
19551         if [ $total -lt $((before_read + kibibytes)) ]; then
19552                 echo "Memory is too small, abort checking"
19553                 return 0
19554         fi
19555
19556         if [ $((before_read + kibibytes)) -gt $after_read ]; then
19557                 error "Ladvise willread should use more memory" \
19558                         "than $kibibytes KiB"
19559         fi
19560
19561         if [ $((no_read + kibibytes)) -gt $after_read ]; then
19562                 error "Ladvise dontneed should release more memory" \
19563                         "than $kibibytes KiB"
19564         fi
19565 }
19566 run_test 255b "check 'lfs ladvise -a dontneed'"
19567
19568 test_255c() {
19569         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
19570                 skip "lustre < 2.10.50 does not support lockahead"
19571
19572         local count
19573         local new_count
19574         local difference
19575         local i
19576         local rc
19577
19578         test_mkdir -p $DIR/$tdir
19579         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19580
19581         #test 10 returns only success/failure
19582         i=10
19583         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19584         rc=$?
19585         if [ $rc -eq 255 ]; then
19586                 error "Ladvise test${i} failed, ${rc}"
19587         fi
19588
19589         #test 11 counts lock enqueue requests, all others count new locks
19590         i=11
19591         count=$(do_facet ost1 \
19592                 $LCTL get_param -n ost.OSS.ost.stats)
19593         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
19594
19595         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19596         rc=$?
19597         if [ $rc -eq 255 ]; then
19598                 error "Ladvise test${i} failed, ${rc}"
19599         fi
19600
19601         new_count=$(do_facet ost1 \
19602                 $LCTL get_param -n ost.OSS.ost.stats)
19603         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
19604                    awk '{ print $2 }')
19605
19606         difference="$((new_count - count))"
19607         if [ $difference -ne $rc ]; then
19608                 error "Ladvise test${i}, bad enqueue count, returned " \
19609                       "${rc}, actual ${difference}"
19610         fi
19611
19612         for i in $(seq 12 21); do
19613                 # If we do not do this, we run the risk of having too many
19614                 # locks and starting lock cancellation while we are checking
19615                 # lock counts.
19616                 cancel_lru_locks osc
19617
19618                 count=$($LCTL get_param -n \
19619                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19620
19621                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
19622                 rc=$?
19623                 if [ $rc -eq 255 ]; then
19624                         error "Ladvise test ${i} failed, ${rc}"
19625                 fi
19626
19627                 new_count=$($LCTL get_param -n \
19628                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19629                 difference="$((new_count - count))"
19630
19631                 # Test 15 output is divided by 100 to map down to valid return
19632                 if [ $i -eq 15 ]; then
19633                         rc="$((rc * 100))"
19634                 fi
19635
19636                 if [ $difference -ne $rc ]; then
19637                         error "Ladvise test ${i}, bad lock count, returned " \
19638                               "${rc}, actual ${difference}"
19639                 fi
19640         done
19641
19642         #test 22 returns only success/failure
19643         i=22
19644         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19645         rc=$?
19646         if [ $rc -eq 255 ]; then
19647                 error "Ladvise test${i} failed, ${rc}"
19648         fi
19649 }
19650 run_test 255c "suite of ladvise lockahead tests"
19651
19652 test_256() {
19653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19654         remote_mds_nodsh && skip "remote MDS with nodsh"
19655         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19656         changelog_users $SINGLEMDS | grep "^cl" &&
19657                 skip "active changelog user"
19658
19659         local cl_user
19660         local cat_sl
19661         local mdt_dev
19662
19663         mdt_dev=$(mdsdevname 1)
19664         echo $mdt_dev
19665
19666         changelog_register || error "changelog_register failed"
19667
19668         rm -rf $DIR/$tdir
19669         mkdir -p $DIR/$tdir
19670
19671         changelog_clear 0 || error "changelog_clear failed"
19672
19673         # change something
19674         touch $DIR/$tdir/{1..10}
19675
19676         # stop the MDT
19677         stop $SINGLEMDS || error "Fail to stop MDT"
19678
19679         # remount the MDT
19680
19681         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
19682
19683         #after mount new plainllog is used
19684         touch $DIR/$tdir/{11..19}
19685         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
19686         stack_trap "rm -f $tmpfile"
19687         cat_sl=$(do_facet $SINGLEMDS "sync; \
19688                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19689                  llog_reader $tmpfile | grep -c type=1064553b")
19690         do_facet $SINGLEMDS llog_reader $tmpfile
19691
19692         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
19693
19694         changelog_clear 0 || error "changelog_clear failed"
19695
19696         cat_sl=$(do_facet $SINGLEMDS "sync; \
19697                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19698                  llog_reader $tmpfile | grep -c type=1064553b")
19699
19700         if (( cat_sl == 2 )); then
19701                 error "Empty plain llog was not deleted from changelog catalog"
19702         elif (( cat_sl != 1 )); then
19703                 error "Active plain llog shouldn't be deleted from catalog"
19704         fi
19705 }
19706 run_test 256 "Check llog delete for empty and not full state"
19707
19708 test_257() {
19709         remote_mds_nodsh && skip "remote MDS with nodsh"
19710         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19711                 skip "Need MDS version at least 2.8.55"
19712
19713         test_mkdir $DIR/$tdir
19714
19715         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
19716                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
19717         stat $DIR/$tdir
19718
19719 #define OBD_FAIL_MDS_XATTR_REP                  0x161
19720         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19721         local facet=mds$((mdtidx + 1))
19722         set_nodes_failloc $(facet_active_host $facet) 0x80000161
19723         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
19724
19725         stop $facet || error "stop MDS failed"
19726         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
19727                 error "start MDS fail"
19728         wait_recovery_complete $facet
19729 }
19730 run_test 257 "xattr locks are not lost"
19731
19732 # Verify we take the i_mutex when security requires it
19733 test_258a() {
19734 #define OBD_FAIL_IMUTEX_SEC 0x141c
19735         $LCTL set_param fail_loc=0x141c
19736         touch $DIR/$tfile
19737         chmod u+s $DIR/$tfile
19738         chmod a+rwx $DIR/$tfile
19739         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19740         RC=$?
19741         if [ $RC -ne 0 ]; then
19742                 error "error, failed to take i_mutex, rc=$?"
19743         fi
19744         rm -f $DIR/$tfile
19745 }
19746 run_test 258a "verify i_mutex security behavior when suid attributes is set"
19747
19748 # Verify we do NOT take the i_mutex in the normal case
19749 test_258b() {
19750 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
19751         $LCTL set_param fail_loc=0x141d
19752         touch $DIR/$tfile
19753         chmod a+rwx $DIR
19754         chmod a+rw $DIR/$tfile
19755         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19756         RC=$?
19757         if [ $RC -ne 0 ]; then
19758                 error "error, took i_mutex unnecessarily, rc=$?"
19759         fi
19760         rm -f $DIR/$tfile
19761
19762 }
19763 run_test 258b "verify i_mutex security behavior"
19764
19765 test_259() {
19766         local file=$DIR/$tfile
19767         local before
19768         local after
19769
19770         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19771
19772         stack_trap "rm -f $file" EXIT
19773
19774         wait_delete_completed
19775         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19776         echo "before: $before"
19777
19778         $LFS setstripe -i 0 -c 1 $file
19779         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
19780         sync_all_data
19781         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19782         echo "after write: $after"
19783
19784 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
19785         do_facet ost1 $LCTL set_param fail_loc=0x2301
19786         $TRUNCATE $file 0
19787         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19788         echo "after truncate: $after"
19789
19790         stop ost1
19791         do_facet ost1 $LCTL set_param fail_loc=0
19792         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19793         sleep 2
19794         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19795         echo "after restart: $after"
19796         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
19797                 error "missing truncate?"
19798
19799         return 0
19800 }
19801 run_test 259 "crash at delayed truncate"
19802
19803 test_260() {
19804 #define OBD_FAIL_MDC_CLOSE               0x806
19805         $LCTL set_param fail_loc=0x80000806
19806         touch $DIR/$tfile
19807
19808 }
19809 run_test 260 "Check mdc_close fail"
19810
19811 ### Data-on-MDT sanity tests ###
19812 test_270a() {
19813         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19814                 skip "Need MDS version at least 2.10.55 for DoM"
19815
19816         # create DoM file
19817         local dom=$DIR/$tdir/dom_file
19818         local tmp=$DIR/$tdir/tmp_file
19819
19820         mkdir -p $DIR/$tdir
19821
19822         # basic checks for DoM component creation
19823         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
19824                 error "Can set MDT layout to non-first entry"
19825
19826         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
19827                 error "Can define multiple entries as MDT layout"
19828
19829         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
19830
19831         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
19832         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
19833         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
19834
19835         local mdtidx=$($LFS getstripe -m $dom)
19836         local mdtname=MDT$(printf %04x $mdtidx)
19837         local facet=mds$((mdtidx + 1))
19838         local space_check=1
19839
19840         # Skip free space checks with ZFS
19841         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
19842
19843         # write
19844         sync
19845         local size_tmp=$((65536 * 3))
19846         local mdtfree1=$(do_facet $facet \
19847                          lctl get_param -n osd*.*$mdtname.kbytesfree)
19848
19849         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19850         # check also direct IO along write
19851         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
19852         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19853         sync
19854         cmp $tmp $dom || error "file data is different"
19855         [ $(stat -c%s $dom) == $size_tmp ] ||
19856                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19857         if [ $space_check == 1 ]; then
19858                 local mdtfree2=$(do_facet $facet \
19859                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
19860
19861                 # increase in usage from by $size_tmp
19862                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19863                         error "MDT free space wrong after write: " \
19864                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19865         fi
19866
19867         # truncate
19868         local size_dom=10000
19869
19870         $TRUNCATE $dom $size_dom
19871         [ $(stat -c%s $dom) == $size_dom ] ||
19872                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
19873         if [ $space_check == 1 ]; then
19874                 mdtfree1=$(do_facet $facet \
19875                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19876                 # decrease in usage from $size_tmp to new $size_dom
19877                 [ $(($mdtfree1 - $mdtfree2)) -ge \
19878                   $(((size_tmp - size_dom) / 1024)) ] ||
19879                         error "MDT free space is wrong after truncate: " \
19880                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
19881         fi
19882
19883         # append
19884         cat $tmp >> $dom
19885         sync
19886         size_dom=$((size_dom + size_tmp))
19887         [ $(stat -c%s $dom) == $size_dom ] ||
19888                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
19889         if [ $space_check == 1 ]; then
19890                 mdtfree2=$(do_facet $facet \
19891                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19892                 # increase in usage by $size_tmp from previous
19893                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19894                         error "MDT free space is wrong after append: " \
19895                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19896         fi
19897
19898         # delete
19899         rm $dom
19900         if [ $space_check == 1 ]; then
19901                 mdtfree1=$(do_facet $facet \
19902                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19903                 # decrease in usage by $size_dom from previous
19904                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
19905                         error "MDT free space is wrong after removal: " \
19906                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
19907         fi
19908
19909         # combined striping
19910         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
19911                 error "Can't create DoM + OST striping"
19912
19913         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
19914         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19915         # check also direct IO along write
19916         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19917         sync
19918         cmp $tmp $dom || error "file data is different"
19919         [ $(stat -c%s $dom) == $size_tmp ] ||
19920                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19921         rm $dom $tmp
19922
19923         return 0
19924 }
19925 run_test 270a "DoM: basic functionality tests"
19926
19927 test_270b() {
19928         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19929                 skip "Need MDS version at least 2.10.55"
19930
19931         local dom=$DIR/$tdir/dom_file
19932         local max_size=1048576
19933
19934         mkdir -p $DIR/$tdir
19935         $LFS setstripe -E $max_size -L mdt $dom
19936
19937         # truncate over the limit
19938         $TRUNCATE $dom $(($max_size + 1)) &&
19939                 error "successful truncate over the maximum size"
19940         # write over the limit
19941         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
19942                 error "successful write over the maximum size"
19943         # append over the limit
19944         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
19945         echo "12345" >> $dom && error "successful append over the maximum size"
19946         rm $dom
19947
19948         return 0
19949 }
19950 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
19951
19952 test_270c() {
19953         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19954                 skip "Need MDS version at least 2.10.55"
19955
19956         mkdir -p $DIR/$tdir
19957         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19958
19959         # check files inherit DoM EA
19960         touch $DIR/$tdir/first
19961         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
19962                 error "bad pattern"
19963         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
19964                 error "bad stripe count"
19965         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
19966                 error "bad stripe size"
19967
19968         # check directory inherits DoM EA and uses it as default
19969         mkdir $DIR/$tdir/subdir
19970         touch $DIR/$tdir/subdir/second
19971         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
19972                 error "bad pattern in sub-directory"
19973         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
19974                 error "bad stripe count in sub-directory"
19975         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
19976                 error "bad stripe size in sub-directory"
19977         return 0
19978 }
19979 run_test 270c "DoM: DoM EA inheritance tests"
19980
19981 test_270d() {
19982         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19983                 skip "Need MDS version at least 2.10.55"
19984
19985         mkdir -p $DIR/$tdir
19986         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19987
19988         # inherit default DoM striping
19989         mkdir $DIR/$tdir/subdir
19990         touch $DIR/$tdir/subdir/f1
19991
19992         # change default directory striping
19993         $LFS setstripe -c 1 $DIR/$tdir/subdir
19994         touch $DIR/$tdir/subdir/f2
19995         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
19996                 error "wrong default striping in file 2"
19997         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
19998                 error "bad pattern in file 2"
19999         return 0
20000 }
20001 run_test 270d "DoM: change striping from DoM to RAID0"
20002
20003 test_270e() {
20004         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20005                 skip "Need MDS version at least 2.10.55"
20006
20007         mkdir -p $DIR/$tdir/dom
20008         mkdir -p $DIR/$tdir/norm
20009         DOMFILES=20
20010         NORMFILES=10
20011         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
20012         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
20013
20014         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
20015         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
20016
20017         # find DoM files by layout
20018         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
20019         [ $NUM -eq  $DOMFILES ] ||
20020                 error "lfs find -L: found $NUM, expected $DOMFILES"
20021         echo "Test 1: lfs find 20 DOM files by layout: OK"
20022
20023         # there should be 1 dir with default DOM striping
20024         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
20025         [ $NUM -eq  1 ] ||
20026                 error "lfs find -L: found $NUM, expected 1 dir"
20027         echo "Test 2: lfs find 1 DOM dir by layout: OK"
20028
20029         # find DoM files by stripe size
20030         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
20031         [ $NUM -eq  $DOMFILES ] ||
20032                 error "lfs find -S: found $NUM, expected $DOMFILES"
20033         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
20034
20035         # find files by stripe offset except DoM files
20036         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
20037         [ $NUM -eq  $NORMFILES ] ||
20038                 error "lfs find -i: found $NUM, expected $NORMFILES"
20039         echo "Test 5: lfs find no DOM files by stripe index: OK"
20040         return 0
20041 }
20042 run_test 270e "DoM: lfs find with DoM files test"
20043
20044 test_270f() {
20045         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20046                 skip "Need MDS version at least 2.10.55"
20047
20048         local mdtname=${FSNAME}-MDT0000-mdtlov
20049         local dom=$DIR/$tdir/dom_file
20050         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
20051                                                 lod.$mdtname.dom_stripesize)
20052         local dom_limit=131072
20053
20054         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
20055         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20056                                                 lod.$mdtname.dom_stripesize)
20057         [ ${dom_limit} -eq ${dom_current} ] ||
20058                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
20059
20060         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20061         $LFS setstripe -d $DIR/$tdir
20062         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
20063                 error "Can't set directory default striping"
20064
20065         # exceed maximum stripe size
20066         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20067                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
20068         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
20069                 error "Able to create DoM component size more than LOD limit"
20070
20071         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20072         dom_current=$(do_facet mds1 $LCTL get_param -n \
20073                                                 lod.$mdtname.dom_stripesize)
20074         [ 0 -eq ${dom_current} ] ||
20075                 error "Can't set zero DoM stripe limit"
20076         rm $dom
20077
20078         # attempt to create DoM file on server with disabled DoM should
20079         # remove DoM entry from layout and be succeed
20080         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20081                 error "Can't create DoM file (DoM is disabled)"
20082         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20083                 error "File has DoM component while DoM is disabled"
20084         rm $dom
20085
20086         # attempt to create DoM file with only DoM stripe should return error
20087         $LFS setstripe -E $dom_limit -L mdt $dom &&
20088                 error "Able to create DoM-only file while DoM is disabled"
20089
20090         # too low values to be aligned with smallest stripe size 64K
20091         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20092         dom_current=$(do_facet mds1 $LCTL get_param -n \
20093                                                 lod.$mdtname.dom_stripesize)
20094         [ 30000 -eq ${dom_current} ] &&
20095                 error "Can set too small DoM stripe limit"
20096
20097         # 64K is a minimal stripe size in Lustre, expect limit of that size
20098         [ 65536 -eq ${dom_current} ] ||
20099                 error "Limit is not set to 64K but ${dom_current}"
20100
20101         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20102         dom_current=$(do_facet mds1 $LCTL get_param -n \
20103                                                 lod.$mdtname.dom_stripesize)
20104         echo $dom_current
20105         [ 2147483648 -eq ${dom_current} ] &&
20106                 error "Can set too large DoM stripe limit"
20107
20108         do_facet mds1 $LCTL set_param -n \
20109                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20110         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20111                 error "Can't create DoM component size after limit change"
20112         do_facet mds1 $LCTL set_param -n \
20113                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20114         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20115                 error "Can't create DoM file after limit decrease"
20116         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20117                 error "Can create big DoM component after limit decrease"
20118         touch ${dom}_def ||
20119                 error "Can't create file with old default layout"
20120
20121         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20122         return 0
20123 }
20124 run_test 270f "DoM: maximum DoM stripe size checks"
20125
20126 test_270g() {
20127         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20128                 skip "Need MDS version at least 2.13.52"
20129         local dom=$DIR/$tdir/$tfile
20130
20131         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20132         local lodname=${FSNAME}-MDT0000-mdtlov
20133
20134         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20135         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20136         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20137         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20138
20139         local dom_limit=1024
20140         local dom_threshold="50%"
20141
20142         $LFS setstripe -d $DIR/$tdir
20143         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20144                 error "Can't set directory default striping"
20145
20146         do_facet mds1 $LCTL set_param -n \
20147                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20148         # set 0 threshold and create DOM file to change tunable stripesize
20149         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20150         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20151                 error "Failed to create $dom file"
20152         # now tunable dom_cur_stripesize should reach maximum
20153         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20154                                         lod.${lodname}.dom_stripesize_cur_kb)
20155         [[ $dom_current == $dom_limit ]] ||
20156                 error "Current DOM stripesize is not maximum"
20157         rm $dom
20158
20159         # set threshold for further tests
20160         do_facet mds1 $LCTL set_param -n \
20161                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20162         echo "DOM threshold is $dom_threshold free space"
20163         local dom_def
20164         local dom_set
20165         # Spoof bfree to exceed threshold
20166         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20167         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20168         for spfree in 40 20 0 15 30 55; do
20169                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20170                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20171                         error "Failed to create $dom file"
20172                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20173                                         lod.${lodname}.dom_stripesize_cur_kb)
20174                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20175                 [[ $dom_def != $dom_current ]] ||
20176                         error "Default stripe size was not changed"
20177                 if [[ $spfree > 0 ]] ; then
20178                         dom_set=$($LFS getstripe -S $dom)
20179                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20180                                 error "DOM component size is still old"
20181                 else
20182                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20183                                 error "DoM component is set with no free space"
20184                 fi
20185                 rm $dom
20186                 dom_current=$dom_def
20187         done
20188 }
20189 run_test 270g "DoM: default DoM stripe size depends on free space"
20190
20191 test_270h() {
20192         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20193                 skip "Need MDS version at least 2.13.53"
20194
20195         local mdtname=${FSNAME}-MDT0000-mdtlov
20196         local dom=$DIR/$tdir/$tfile
20197         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20198
20199         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20200         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20201
20202         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20203         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20204                 error "can't create OST file"
20205         # mirrored file with DOM entry in the second mirror
20206         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20207                 error "can't create mirror with DoM component"
20208
20209         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20210
20211         # DOM component in the middle and has other enries in the same mirror,
20212         # should succeed but lost DoM component
20213         $LFS setstripe --copy=${dom}_1 $dom ||
20214                 error "Can't create file from OST|DOM mirror layout"
20215         # check new file has no DoM layout after all
20216         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20217                 error "File has DoM component while DoM is disabled"
20218 }
20219 run_test 270h "DoM: DoM stripe removal when disabled on server"
20220
20221 test_271a() {
20222         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20223                 skip "Need MDS version at least 2.10.55"
20224
20225         local dom=$DIR/$tdir/dom
20226
20227         mkdir -p $DIR/$tdir
20228
20229         $LFS setstripe -E 1024K -L mdt $dom
20230
20231         lctl set_param -n mdc.*.stats=clear
20232         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20233         cat $dom > /dev/null
20234         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20235         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20236         ls $dom
20237         rm -f $dom
20238 }
20239 run_test 271a "DoM: data is cached for read after write"
20240
20241 test_271b() {
20242         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20243                 skip "Need MDS version at least 2.10.55"
20244
20245         local dom=$DIR/$tdir/dom
20246
20247         mkdir -p $DIR/$tdir
20248
20249         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20250
20251         lctl set_param -n mdc.*.stats=clear
20252         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20253         cancel_lru_locks mdc
20254         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20255         # second stat to check size is cached on client
20256         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20257         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20258         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20259         rm -f $dom
20260 }
20261 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20262
20263 test_271ba() {
20264         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20265                 skip "Need MDS version at least 2.10.55"
20266
20267         local dom=$DIR/$tdir/dom
20268
20269         mkdir -p $DIR/$tdir
20270
20271         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20272
20273         lctl set_param -n mdc.*.stats=clear
20274         lctl set_param -n osc.*.stats=clear
20275         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20276         cancel_lru_locks mdc
20277         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20278         # second stat to check size is cached on client
20279         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20280         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20281         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20282         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20283         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20284         rm -f $dom
20285 }
20286 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20287
20288
20289 get_mdc_stats() {
20290         local mdtidx=$1
20291         local param=$2
20292         local mdt=MDT$(printf %04x $mdtidx)
20293
20294         if [ -z $param ]; then
20295                 lctl get_param -n mdc.*$mdt*.stats
20296         else
20297                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20298         fi
20299 }
20300
20301 test_271c() {
20302         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20303                 skip "Need MDS version at least 2.10.55"
20304
20305         local dom=$DIR/$tdir/dom
20306
20307         mkdir -p $DIR/$tdir
20308
20309         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20310
20311         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20312         local facet=mds$((mdtidx + 1))
20313
20314         cancel_lru_locks mdc
20315         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20316         createmany -o $dom 1000
20317         lctl set_param -n mdc.*.stats=clear
20318         smalliomany -w $dom 1000 200
20319         get_mdc_stats $mdtidx
20320         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20321         # Each file has 1 open, 1 IO enqueues, total 2000
20322         # but now we have also +1 getxattr for security.capability, total 3000
20323         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20324         unlinkmany $dom 1000
20325
20326         cancel_lru_locks mdc
20327         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20328         createmany -o $dom 1000
20329         lctl set_param -n mdc.*.stats=clear
20330         smalliomany -w $dom 1000 200
20331         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20332         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20333         # for OPEN and IO lock.
20334         [ $((enq - enq_2)) -ge 1000 ] ||
20335                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20336         unlinkmany $dom 1000
20337         return 0
20338 }
20339 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20340
20341 cleanup_271def_tests() {
20342         trap 0
20343         rm -f $1
20344 }
20345
20346 test_271d() {
20347         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20348                 skip "Need MDS version at least 2.10.57"
20349
20350         local dom=$DIR/$tdir/dom
20351         local tmp=$TMP/$tfile
20352         trap "cleanup_271def_tests $tmp" EXIT
20353
20354         mkdir -p $DIR/$tdir
20355
20356         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20357
20358         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20359
20360         cancel_lru_locks mdc
20361         dd if=/dev/urandom of=$tmp bs=1000 count=1
20362         dd if=$tmp of=$dom bs=1000 count=1
20363         cancel_lru_locks mdc
20364
20365         cat /etc/hosts >> $tmp
20366         lctl set_param -n mdc.*.stats=clear
20367
20368         # append data to the same file it should update local page
20369         echo "Append to the same page"
20370         cat /etc/hosts >> $dom
20371         local num=$(get_mdc_stats $mdtidx ost_read)
20372         local ra=$(get_mdc_stats $mdtidx req_active)
20373         local rw=$(get_mdc_stats $mdtidx req_waittime)
20374
20375         [ -z $num ] || error "$num READ RPC occured"
20376         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20377         echo "... DONE"
20378
20379         # compare content
20380         cmp $tmp $dom || error "file miscompare"
20381
20382         cancel_lru_locks mdc
20383         lctl set_param -n mdc.*.stats=clear
20384
20385         echo "Open and read file"
20386         cat $dom > /dev/null
20387         local num=$(get_mdc_stats $mdtidx ost_read)
20388         local ra=$(get_mdc_stats $mdtidx req_active)
20389         local rw=$(get_mdc_stats $mdtidx req_waittime)
20390
20391         [ -z $num ] || error "$num READ RPC occured"
20392         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20393         echo "... DONE"
20394
20395         # compare content
20396         cmp $tmp $dom || error "file miscompare"
20397
20398         return 0
20399 }
20400 run_test 271d "DoM: read on open (1K file in reply buffer)"
20401
20402 test_271f() {
20403         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20404                 skip "Need MDS version at least 2.10.57"
20405
20406         local dom=$DIR/$tdir/dom
20407         local tmp=$TMP/$tfile
20408         trap "cleanup_271def_tests $tmp" EXIT
20409
20410         mkdir -p $DIR/$tdir
20411
20412         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20413
20414         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20415
20416         cancel_lru_locks mdc
20417         dd if=/dev/urandom of=$tmp bs=265000 count=1
20418         dd if=$tmp of=$dom bs=265000 count=1
20419         cancel_lru_locks mdc
20420         cat /etc/hosts >> $tmp
20421         lctl set_param -n mdc.*.stats=clear
20422
20423         echo "Append to the same page"
20424         cat /etc/hosts >> $dom
20425         local num=$(get_mdc_stats $mdtidx ost_read)
20426         local ra=$(get_mdc_stats $mdtidx req_active)
20427         local rw=$(get_mdc_stats $mdtidx req_waittime)
20428
20429         [ -z $num ] || error "$num READ RPC occured"
20430         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20431         echo "... DONE"
20432
20433         # compare content
20434         cmp $tmp $dom || error "file miscompare"
20435
20436         cancel_lru_locks mdc
20437         lctl set_param -n mdc.*.stats=clear
20438
20439         echo "Open and read file"
20440         cat $dom > /dev/null
20441         local num=$(get_mdc_stats $mdtidx ost_read)
20442         local ra=$(get_mdc_stats $mdtidx req_active)
20443         local rw=$(get_mdc_stats $mdtidx req_waittime)
20444
20445         [ -z $num ] && num=0
20446         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20447         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20448         echo "... DONE"
20449
20450         # compare content
20451         cmp $tmp $dom || error "file miscompare"
20452
20453         return 0
20454 }
20455 run_test 271f "DoM: read on open (200K file and read tail)"
20456
20457 test_271g() {
20458         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20459                 skip "Skipping due to old client or server version"
20460
20461         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20462         # to get layout
20463         $CHECKSTAT -t file $DIR1/$tfile
20464
20465         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20466         MULTIOP_PID=$!
20467         sleep 1
20468         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20469         $LCTL set_param fail_loc=0x80000314
20470         rm $DIR1/$tfile || error "Unlink fails"
20471         RC=$?
20472         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20473         [ $RC -eq 0 ] || error "Failed write to stale object"
20474 }
20475 run_test 271g "Discard DoM data vs client flush race"
20476
20477 test_272a() {
20478         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20479                 skip "Need MDS version at least 2.11.50"
20480
20481         local dom=$DIR/$tdir/dom
20482         mkdir -p $DIR/$tdir
20483
20484         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20485         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20486                 error "failed to write data into $dom"
20487         local old_md5=$(md5sum $dom)
20488
20489         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20490                 error "failed to migrate to the same DoM component"
20491
20492         local new_md5=$(md5sum $dom)
20493
20494         [ "$old_md5" == "$new_md5" ] ||
20495                 error "md5sum differ: $old_md5, $new_md5"
20496
20497         [ $($LFS getstripe -c $dom) -eq 2 ] ||
20498                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
20499 }
20500 run_test 272a "DoM migration: new layout with the same DOM component"
20501
20502 test_272b() {
20503         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20504                 skip "Need MDS version at least 2.11.50"
20505
20506         local dom=$DIR/$tdir/dom
20507         mkdir -p $DIR/$tdir
20508         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20509
20510         local mdtidx=$($LFS getstripe -m $dom)
20511         local mdtname=MDT$(printf %04x $mdtidx)
20512         local facet=mds$((mdtidx + 1))
20513
20514         local mdtfree1=$(do_facet $facet \
20515                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20516         dd if=/dev/urandom of=$dom bs=2M count=1 ||
20517                 error "failed to write data into $dom"
20518         local old_md5=$(md5sum $dom)
20519         cancel_lru_locks mdc
20520         local mdtfree1=$(do_facet $facet \
20521                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20522
20523         $LFS migrate -c2 $dom ||
20524                 error "failed to migrate to the new composite layout"
20525         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20526                 error "MDT stripe was not removed"
20527
20528         cancel_lru_locks mdc
20529         local new_md5=$(md5sum $dom)
20530         [ "$old_md5" == "$new_md5" ] ||
20531                 error "$old_md5 != $new_md5"
20532
20533         # Skip free space checks with ZFS
20534         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20535                 local mdtfree2=$(do_facet $facet \
20536                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20537                 [ $mdtfree2 -gt $mdtfree1 ] ||
20538                         error "MDT space is not freed after migration"
20539         fi
20540         return 0
20541 }
20542 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
20543
20544 test_272c() {
20545         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20546                 skip "Need MDS version at least 2.11.50"
20547
20548         local dom=$DIR/$tdir/$tfile
20549         mkdir -p $DIR/$tdir
20550         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20551
20552         local mdtidx=$($LFS getstripe -m $dom)
20553         local mdtname=MDT$(printf %04x $mdtidx)
20554         local facet=mds$((mdtidx + 1))
20555
20556         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20557                 error "failed to write data into $dom"
20558         local old_md5=$(md5sum $dom)
20559         cancel_lru_locks mdc
20560         local mdtfree1=$(do_facet $facet \
20561                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20562
20563         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
20564                 error "failed to migrate to the new composite layout"
20565         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
20566                 error "MDT stripe was not removed"
20567
20568         cancel_lru_locks mdc
20569         local new_md5=$(md5sum $dom)
20570         [ "$old_md5" == "$new_md5" ] ||
20571                 error "$old_md5 != $new_md5"
20572
20573         # Skip free space checks with ZFS
20574         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20575                 local mdtfree2=$(do_facet $facet \
20576                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20577                 [ $mdtfree2 -gt $mdtfree1 ] ||
20578                         error "MDS space is not freed after migration"
20579         fi
20580         return 0
20581 }
20582 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
20583
20584 test_272d() {
20585         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20586                 skip "Need MDS version at least 2.12.55"
20587
20588         local dom=$DIR/$tdir/$tfile
20589         mkdir -p $DIR/$tdir
20590         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20591
20592         local mdtidx=$($LFS getstripe -m $dom)
20593         local mdtname=MDT$(printf %04x $mdtidx)
20594         local facet=mds$((mdtidx + 1))
20595
20596         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20597                 error "failed to write data into $dom"
20598         local old_md5=$(md5sum $dom)
20599         cancel_lru_locks mdc
20600         local mdtfree1=$(do_facet $facet \
20601                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20602
20603         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
20604                 error "failed mirroring to the new composite layout"
20605         $LFS mirror resync $dom ||
20606                 error "failed mirror resync"
20607         $LFS mirror split --mirror-id 1 -d $dom ||
20608                 error "failed mirror split"
20609
20610         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20611                 error "MDT stripe was not removed"
20612
20613         cancel_lru_locks mdc
20614         local new_md5=$(md5sum $dom)
20615         [ "$old_md5" == "$new_md5" ] ||
20616                 error "$old_md5 != $new_md5"
20617
20618         # Skip free space checks with ZFS
20619         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20620                 local mdtfree2=$(do_facet $facet \
20621                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20622                 [ $mdtfree2 -gt $mdtfree1 ] ||
20623                         error "MDS space is not freed after DOM mirror deletion"
20624         fi
20625         return 0
20626 }
20627 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
20628
20629 test_272e() {
20630         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20631                 skip "Need MDS version at least 2.12.55"
20632
20633         local dom=$DIR/$tdir/$tfile
20634         mkdir -p $DIR/$tdir
20635         $LFS setstripe -c 2 $dom
20636
20637         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20638                 error "failed to write data into $dom"
20639         local old_md5=$(md5sum $dom)
20640         cancel_lru_locks mdc
20641
20642         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
20643                 error "failed mirroring to the DOM layout"
20644         $LFS mirror resync $dom ||
20645                 error "failed mirror resync"
20646         $LFS mirror split --mirror-id 1 -d $dom ||
20647                 error "failed mirror split"
20648
20649         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20650                 error "MDT stripe was not removed"
20651
20652         cancel_lru_locks mdc
20653         local new_md5=$(md5sum $dom)
20654         [ "$old_md5" == "$new_md5" ] ||
20655                 error "$old_md5 != $new_md5"
20656
20657         return 0
20658 }
20659 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
20660
20661 test_272f() {
20662         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20663                 skip "Need MDS version at least 2.12.55"
20664
20665         local dom=$DIR/$tdir/$tfile
20666         mkdir -p $DIR/$tdir
20667         $LFS setstripe -c 2 $dom
20668
20669         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20670                 error "failed to write data into $dom"
20671         local old_md5=$(md5sum $dom)
20672         cancel_lru_locks mdc
20673
20674         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
20675                 error "failed migrating to the DOM file"
20676
20677         cancel_lru_locks mdc
20678         local new_md5=$(md5sum $dom)
20679         [ "$old_md5" != "$new_md5" ] &&
20680                 error "$old_md5 != $new_md5"
20681
20682         return 0
20683 }
20684 run_test 272f "DoM migration: OST-striped file to DOM file"
20685
20686 test_273a() {
20687         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20688                 skip "Need MDS version at least 2.11.50"
20689
20690         # Layout swap cannot be done if either file has DOM component,
20691         # this will never be supported, migration should be used instead
20692
20693         local dom=$DIR/$tdir/$tfile
20694         mkdir -p $DIR/$tdir
20695
20696         $LFS setstripe -c2 ${dom}_plain
20697         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
20698         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
20699                 error "can swap layout with DoM component"
20700         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
20701                 error "can swap layout with DoM component"
20702
20703         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
20704         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
20705                 error "can swap layout with DoM component"
20706         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
20707                 error "can swap layout with DoM component"
20708         return 0
20709 }
20710 run_test 273a "DoM: layout swapping should fail with DOM"
20711
20712 test_275() {
20713         remote_ost_nodsh && skip "remote OST with nodsh"
20714         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
20715                 skip "Need OST version >= 2.10.57"
20716
20717         local file=$DIR/$tfile
20718         local oss
20719
20720         oss=$(comma_list $(osts_nodes))
20721
20722         dd if=/dev/urandom of=$file bs=1M count=2 ||
20723                 error "failed to create a file"
20724         cancel_lru_locks osc
20725
20726         #lock 1
20727         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20728                 error "failed to read a file"
20729
20730 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
20731         $LCTL set_param fail_loc=0x8000031f
20732
20733         cancel_lru_locks osc &
20734         sleep 1
20735
20736 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
20737         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
20738         #IO takes another lock, but matches the PENDING one
20739         #and places it to the IO RPC
20740         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20741                 error "failed to read a file with PENDING lock"
20742 }
20743 run_test 275 "Read on a canceled duplicate lock"
20744
20745 test_276() {
20746         remote_ost_nodsh && skip "remote OST with nodsh"
20747         local pid
20748
20749         do_facet ost1 "(while true; do \
20750                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
20751                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
20752         pid=$!
20753
20754         for LOOP in $(seq 20); do
20755                 stop ost1
20756                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
20757         done
20758         kill -9 $pid
20759         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
20760                 rm $TMP/sanity_276_pid"
20761 }
20762 run_test 276 "Race between mount and obd_statfs"
20763
20764 test_277() {
20765         $LCTL set_param ldlm.namespaces.*.lru_size=0
20766         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
20767         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20768                         grep ^used_mb | awk '{print $2}')
20769         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
20770         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
20771                 oflag=direct conv=notrunc
20772         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20773                         grep ^used_mb | awk '{print $2}')
20774         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
20775 }
20776 run_test 277 "Direct IO shall drop page cache"
20777
20778 test_278() {
20779         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20780         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20781         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
20782                 skip "needs the same host for mdt1 mdt2" && return
20783
20784         local pid1
20785         local pid2
20786
20787 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
20788         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
20789         stop mds2 &
20790         pid2=$!
20791
20792         stop mds1
20793
20794         echo "Starting MDTs"
20795         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20796         wait $pid2
20797 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
20798 #will return NULL
20799         do_facet mds2 $LCTL set_param fail_loc=0
20800
20801         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
20802         wait_recovery_complete mds2
20803 }
20804 run_test 278 "Race starting MDS between MDTs stop/start"
20805
20806 test_280() {
20807         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
20808                 skip "Need MGS version at least 2.13.52"
20809         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20810         combined_mgs_mds || skip "needs combined MGS/MDT"
20811
20812         umount_client $MOUNT
20813 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
20814         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
20815
20816         mount_client $MOUNT &
20817         sleep 1
20818         stop mgs || error "stop mgs failed"
20819         #for a race mgs would crash
20820         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
20821         mount_client $MOUNT || error "mount client failed"
20822 }
20823 run_test 280 "Race between MGS umount and client llog processing"
20824
20825 cleanup_test_300() {
20826         trap 0
20827         umask $SAVE_UMASK
20828 }
20829 test_striped_dir() {
20830         local mdt_index=$1
20831         local stripe_count
20832         local stripe_index
20833
20834         mkdir -p $DIR/$tdir
20835
20836         SAVE_UMASK=$(umask)
20837         trap cleanup_test_300 RETURN EXIT
20838
20839         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
20840                                                 $DIR/$tdir/striped_dir ||
20841                 error "set striped dir error"
20842
20843         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
20844         [ "$mode" = "755" ] || error "expect 755 got $mode"
20845
20846         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
20847                 error "getdirstripe failed"
20848         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
20849         if [ "$stripe_count" != "2" ]; then
20850                 error "1:stripe_count is $stripe_count, expect 2"
20851         fi
20852         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
20853         if [ "$stripe_count" != "2" ]; then
20854                 error "2:stripe_count is $stripe_count, expect 2"
20855         fi
20856
20857         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
20858         if [ "$stripe_index" != "$mdt_index" ]; then
20859                 error "stripe_index is $stripe_index, expect $mdt_index"
20860         fi
20861
20862         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20863                 error "nlink error after create striped dir"
20864
20865         mkdir $DIR/$tdir/striped_dir/a
20866         mkdir $DIR/$tdir/striped_dir/b
20867
20868         stat $DIR/$tdir/striped_dir/a ||
20869                 error "create dir under striped dir failed"
20870         stat $DIR/$tdir/striped_dir/b ||
20871                 error "create dir under striped dir failed"
20872
20873         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
20874                 error "nlink error after mkdir"
20875
20876         rmdir $DIR/$tdir/striped_dir/a
20877         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
20878                 error "nlink error after rmdir"
20879
20880         rmdir $DIR/$tdir/striped_dir/b
20881         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20882                 error "nlink error after rmdir"
20883
20884         chattr +i $DIR/$tdir/striped_dir
20885         createmany -o $DIR/$tdir/striped_dir/f 10 &&
20886                 error "immutable flags not working under striped dir!"
20887         chattr -i $DIR/$tdir/striped_dir
20888
20889         rmdir $DIR/$tdir/striped_dir ||
20890                 error "rmdir striped dir error"
20891
20892         cleanup_test_300
20893
20894         true
20895 }
20896
20897 test_300a() {
20898         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20899                 skip "skipped for lustre < 2.7.0"
20900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20901         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20902
20903         test_striped_dir 0 || error "failed on striped dir on MDT0"
20904         test_striped_dir 1 || error "failed on striped dir on MDT0"
20905 }
20906 run_test 300a "basic striped dir sanity test"
20907
20908 test_300b() {
20909         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20910                 skip "skipped for lustre < 2.7.0"
20911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20912         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20913
20914         local i
20915         local mtime1
20916         local mtime2
20917         local mtime3
20918
20919         test_mkdir $DIR/$tdir || error "mkdir fail"
20920         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20921                 error "set striped dir error"
20922         for i in {0..9}; do
20923                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
20924                 sleep 1
20925                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
20926                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
20927                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
20928                 sleep 1
20929                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
20930                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
20931                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
20932         done
20933         true
20934 }
20935 run_test 300b "check ctime/mtime for striped dir"
20936
20937 test_300c() {
20938         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20939                 skip "skipped for lustre < 2.7.0"
20940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20941         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20942
20943         local file_count
20944
20945         mkdir -p $DIR/$tdir
20946         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
20947                 error "set striped dir error"
20948
20949         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
20950                 error "chown striped dir failed"
20951
20952         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
20953                 error "create 5k files failed"
20954
20955         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
20956
20957         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
20958
20959         rm -rf $DIR/$tdir
20960 }
20961 run_test 300c "chown && check ls under striped directory"
20962
20963 test_300d() {
20964         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20965                 skip "skipped for lustre < 2.7.0"
20966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20967         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20968
20969         local stripe_count
20970         local file
20971
20972         mkdir -p $DIR/$tdir
20973         $LFS setstripe -c 2 $DIR/$tdir
20974
20975         #local striped directory
20976         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20977                 error "set striped dir error"
20978         #look at the directories for debug purposes
20979         ls -l $DIR/$tdir
20980         $LFS getdirstripe $DIR/$tdir
20981         ls -l $DIR/$tdir/striped_dir
20982         $LFS getdirstripe $DIR/$tdir/striped_dir
20983         createmany -o $DIR/$tdir/striped_dir/f 10 ||
20984                 error "create 10 files failed"
20985
20986         #remote striped directory
20987         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
20988                 error "set striped dir error"
20989         #look at the directories for debug purposes
20990         ls -l $DIR/$tdir
20991         $LFS getdirstripe $DIR/$tdir
20992         ls -l $DIR/$tdir/remote_striped_dir
20993         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
20994         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
20995                 error "create 10 files failed"
20996
20997         for file in $(find $DIR/$tdir); do
20998                 stripe_count=$($LFS getstripe -c $file)
20999                 [ $stripe_count -eq 2 ] ||
21000                         error "wrong stripe $stripe_count for $file"
21001         done
21002
21003         rm -rf $DIR/$tdir
21004 }
21005 run_test 300d "check default stripe under striped directory"
21006
21007 test_300e() {
21008         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21009                 skip "Need MDS version at least 2.7.55"
21010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21011         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21012
21013         local stripe_count
21014         local file
21015
21016         mkdir -p $DIR/$tdir
21017
21018         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21019                 error "set striped dir error"
21020
21021         touch $DIR/$tdir/striped_dir/a
21022         touch $DIR/$tdir/striped_dir/b
21023         touch $DIR/$tdir/striped_dir/c
21024
21025         mkdir $DIR/$tdir/striped_dir/dir_a
21026         mkdir $DIR/$tdir/striped_dir/dir_b
21027         mkdir $DIR/$tdir/striped_dir/dir_c
21028
21029         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
21030                 error "set striped adir under striped dir error"
21031
21032         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
21033                 error "set striped bdir under striped dir error"
21034
21035         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
21036                 error "set striped cdir under striped dir error"
21037
21038         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
21039                 error "rename dir under striped dir fails"
21040
21041         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
21042                 error "rename dir under different stripes fails"
21043
21044         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
21045                 error "rename file under striped dir should succeed"
21046
21047         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
21048                 error "rename dir under striped dir should succeed"
21049
21050         rm -rf $DIR/$tdir
21051 }
21052 run_test 300e "check rename under striped directory"
21053
21054 test_300f() {
21055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21056         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21057         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21058                 skip "Need MDS version at least 2.7.55"
21059
21060         local stripe_count
21061         local file
21062
21063         rm -rf $DIR/$tdir
21064         mkdir -p $DIR/$tdir
21065
21066         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21067                 error "set striped dir error"
21068
21069         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
21070                 error "set striped dir error"
21071
21072         touch $DIR/$tdir/striped_dir/a
21073         mkdir $DIR/$tdir/striped_dir/dir_a
21074         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
21075                 error "create striped dir under striped dir fails"
21076
21077         touch $DIR/$tdir/striped_dir1/b
21078         mkdir $DIR/$tdir/striped_dir1/dir_b
21079         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21080                 error "create striped dir under striped dir fails"
21081
21082         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21083                 error "rename dir under different striped dir should fail"
21084
21085         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21086                 error "rename striped dir under diff striped dir should fail"
21087
21088         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21089                 error "rename file under diff striped dirs fails"
21090
21091         rm -rf $DIR/$tdir
21092 }
21093 run_test 300f "check rename cross striped directory"
21094
21095 test_300_check_default_striped_dir()
21096 {
21097         local dirname=$1
21098         local default_count=$2
21099         local default_index=$3
21100         local stripe_count
21101         local stripe_index
21102         local dir_stripe_index
21103         local dir
21104
21105         echo "checking $dirname $default_count $default_index"
21106         $LFS setdirstripe -D -c $default_count -i $default_index \
21107                                 -t all_char $DIR/$tdir/$dirname ||
21108                 error "set default stripe on striped dir error"
21109         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21110         [ $stripe_count -eq $default_count ] ||
21111                 error "expect $default_count get $stripe_count for $dirname"
21112
21113         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21114         [ $stripe_index -eq $default_index ] ||
21115                 error "expect $default_index get $stripe_index for $dirname"
21116
21117         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21118                                                 error "create dirs failed"
21119
21120         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21121         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21122         for dir in $(find $DIR/$tdir/$dirname/*); do
21123                 stripe_count=$($LFS getdirstripe -c $dir)
21124                 [ $stripe_count -eq $default_count ] ||
21125                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
21126                 error "stripe count $default_count != $stripe_count for $dir"
21127
21128                 stripe_index=$($LFS getdirstripe -i $dir)
21129                 [ $default_index -eq -1 ] ||
21130                         [ $stripe_index -eq $default_index ] ||
21131                         error "$stripe_index != $default_index for $dir"
21132
21133                 #check default stripe
21134                 stripe_count=$($LFS getdirstripe -D -c $dir)
21135                 [ $stripe_count -eq $default_count ] ||
21136                 error "default count $default_count != $stripe_count for $dir"
21137
21138                 stripe_index=$($LFS getdirstripe -D -i $dir)
21139                 [ $stripe_index -eq $default_index ] ||
21140                 error "default index $default_index != $stripe_index for $dir"
21141         done
21142         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21143 }
21144
21145 test_300g() {
21146         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21147         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21148                 skip "Need MDS version at least 2.7.55"
21149
21150         local dir
21151         local stripe_count
21152         local stripe_index
21153
21154         mkdir $DIR/$tdir
21155         mkdir $DIR/$tdir/normal_dir
21156
21157         #Checking when client cache stripe index
21158         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21159         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21160                 error "create striped_dir failed"
21161
21162         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21163                 error "create dir0 fails"
21164         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21165         [ $stripe_index -eq 0 ] ||
21166                 error "dir0 expect index 0 got $stripe_index"
21167
21168         mkdir $DIR/$tdir/striped_dir/dir1 ||
21169                 error "create dir1 fails"
21170         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21171         [ $stripe_index -eq 1 ] ||
21172                 error "dir1 expect index 1 got $stripe_index"
21173
21174         #check default stripe count/stripe index
21175         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21176         test_300_check_default_striped_dir normal_dir 1 0
21177         test_300_check_default_striped_dir normal_dir 2 1
21178         test_300_check_default_striped_dir normal_dir 2 -1
21179
21180         #delete default stripe information
21181         echo "delete default stripeEA"
21182         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21183                 error "set default stripe on striped dir error"
21184
21185         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21186         for dir in $(find $DIR/$tdir/normal_dir/*); do
21187                 stripe_count=$($LFS getdirstripe -c $dir)
21188                 [ $stripe_count -eq 0 ] ||
21189                         error "expect 1 get $stripe_count for $dir"
21190                 stripe_index=$($LFS getdirstripe -i $dir)
21191                 [ $stripe_index -eq 0 ] ||
21192                         error "expect 0 get $stripe_index for $dir"
21193         done
21194 }
21195 run_test 300g "check default striped directory for normal directory"
21196
21197 test_300h() {
21198         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21199         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21200                 skip "Need MDS version at least 2.7.55"
21201
21202         local dir
21203         local stripe_count
21204
21205         mkdir $DIR/$tdir
21206         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21207                 error "set striped dir error"
21208
21209         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21210         test_300_check_default_striped_dir striped_dir 1 0
21211         test_300_check_default_striped_dir striped_dir 2 1
21212         test_300_check_default_striped_dir striped_dir 2 -1
21213
21214         #delete default stripe information
21215         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21216                 error "set default stripe on striped dir error"
21217
21218         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21219         for dir in $(find $DIR/$tdir/striped_dir/*); do
21220                 stripe_count=$($LFS getdirstripe -c $dir)
21221                 [ $stripe_count -eq 0 ] ||
21222                         error "expect 1 get $stripe_count for $dir"
21223         done
21224 }
21225 run_test 300h "check default striped directory for striped directory"
21226
21227 test_300i() {
21228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21229         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21230         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21231                 skip "Need MDS version at least 2.7.55"
21232
21233         local stripe_count
21234         local file
21235
21236         mkdir $DIR/$tdir
21237
21238         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21239                 error "set striped dir error"
21240
21241         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21242                 error "create files under striped dir failed"
21243
21244         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21245                 error "set striped hashdir error"
21246
21247         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21248                 error "create dir0 under hash dir failed"
21249         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21250                 error "create dir1 under hash dir failed"
21251
21252         # unfortunately, we need to umount to clear dir layout cache for now
21253         # once we fully implement dir layout, we can drop this
21254         umount_client $MOUNT || error "umount failed"
21255         mount_client $MOUNT || error "mount failed"
21256
21257         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21258         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21259         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21260
21261         #set the stripe to be unknown hash type
21262         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21263         $LCTL set_param fail_loc=0x1901
21264         for ((i = 0; i < 10; i++)); do
21265                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21266                         error "stat f-$i failed"
21267                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21268         done
21269
21270         touch $DIR/$tdir/striped_dir/f0 &&
21271                 error "create under striped dir with unknown hash should fail"
21272
21273         $LCTL set_param fail_loc=0
21274
21275         umount_client $MOUNT || error "umount failed"
21276         mount_client $MOUNT || error "mount failed"
21277
21278         return 0
21279 }
21280 run_test 300i "client handle unknown hash type striped directory"
21281
21282 test_300j() {
21283         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21285         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21286                 skip "Need MDS version at least 2.7.55"
21287
21288         local stripe_count
21289         local file
21290
21291         mkdir $DIR/$tdir
21292
21293         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21294         $LCTL set_param fail_loc=0x1702
21295         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21296                 error "set striped dir error"
21297
21298         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21299                 error "create files under striped dir failed"
21300
21301         $LCTL set_param fail_loc=0
21302
21303         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21304
21305         return 0
21306 }
21307 run_test 300j "test large update record"
21308
21309 test_300k() {
21310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21311         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21312         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21313                 skip "Need MDS version at least 2.7.55"
21314
21315         # this test needs a huge transaction
21316         local kb
21317         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21318              osd*.$FSNAME-MDT0000.kbytestotal")
21319         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21320
21321         local stripe_count
21322         local file
21323
21324         mkdir $DIR/$tdir
21325
21326         #define OBD_FAIL_LARGE_STRIPE   0x1703
21327         $LCTL set_param fail_loc=0x1703
21328         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21329                 error "set striped dir error"
21330         $LCTL set_param fail_loc=0
21331
21332         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21333                 error "getstripeddir fails"
21334         rm -rf $DIR/$tdir/striped_dir ||
21335                 error "unlink striped dir fails"
21336
21337         return 0
21338 }
21339 run_test 300k "test large striped directory"
21340
21341 test_300l() {
21342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21343         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21344         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21345                 skip "Need MDS version at least 2.7.55"
21346
21347         local stripe_index
21348
21349         test_mkdir -p $DIR/$tdir/striped_dir
21350         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21351                         error "chown $RUNAS_ID failed"
21352         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21353                 error "set default striped dir failed"
21354
21355         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21356         $LCTL set_param fail_loc=0x80000158
21357         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21358
21359         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21360         [ $stripe_index -eq 1 ] ||
21361                 error "expect 1 get $stripe_index for $dir"
21362 }
21363 run_test 300l "non-root user to create dir under striped dir with stale layout"
21364
21365 test_300m() {
21366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21367         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21368         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21369                 skip "Need MDS version at least 2.7.55"
21370
21371         mkdir -p $DIR/$tdir/striped_dir
21372         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21373                 error "set default stripes dir error"
21374
21375         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21376
21377         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21378         [ $stripe_count -eq 0 ] ||
21379                         error "expect 0 get $stripe_count for a"
21380
21381         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21382                 error "set default stripes dir error"
21383
21384         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21385
21386         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21387         [ $stripe_count -eq 0 ] ||
21388                         error "expect 0 get $stripe_count for b"
21389
21390         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21391                 error "set default stripes dir error"
21392
21393         mkdir $DIR/$tdir/striped_dir/c &&
21394                 error "default stripe_index is invalid, mkdir c should fails"
21395
21396         rm -rf $DIR/$tdir || error "rmdir fails"
21397 }
21398 run_test 300m "setstriped directory on single MDT FS"
21399
21400 cleanup_300n() {
21401         local list=$(comma_list $(mdts_nodes))
21402
21403         trap 0
21404         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21405 }
21406
21407 test_300n() {
21408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21409         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21410         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21411                 skip "Need MDS version at least 2.7.55"
21412         remote_mds_nodsh && skip "remote MDS with nodsh"
21413
21414         local stripe_index
21415         local list=$(comma_list $(mdts_nodes))
21416
21417         trap cleanup_300n RETURN EXIT
21418         mkdir -p $DIR/$tdir
21419         chmod 777 $DIR/$tdir
21420         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21421                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21422                 error "create striped dir succeeds with gid=0"
21423
21424         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21425         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21426                 error "create striped dir fails with gid=-1"
21427
21428         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21429         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21430                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21431                 error "set default striped dir succeeds with gid=0"
21432
21433
21434         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21435         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21436                 error "set default striped dir fails with gid=-1"
21437
21438
21439         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21440         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21441                                         error "create test_dir fails"
21442         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21443                                         error "create test_dir1 fails"
21444         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21445                                         error "create test_dir2 fails"
21446         cleanup_300n
21447 }
21448 run_test 300n "non-root user to create dir under striped dir with default EA"
21449
21450 test_300o() {
21451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21452         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21453         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21454                 skip "Need MDS version at least 2.7.55"
21455
21456         local numfree1
21457         local numfree2
21458
21459         mkdir -p $DIR/$tdir
21460
21461         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21462         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21463         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21464                 skip "not enough free inodes $numfree1 $numfree2"
21465         fi
21466
21467         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21468         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21469         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21470                 skip "not enough free space $numfree1 $numfree2"
21471         fi
21472
21473         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21474                 error "setdirstripe fails"
21475
21476         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21477                 error "create dirs fails"
21478
21479         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21480         ls $DIR/$tdir/striped_dir > /dev/null ||
21481                 error "ls striped dir fails"
21482         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21483                 error "unlink big striped dir fails"
21484 }
21485 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21486
21487 test_300p() {
21488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21489         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21490         remote_mds_nodsh && skip "remote MDS with nodsh"
21491
21492         mkdir -p $DIR/$tdir
21493
21494         #define OBD_FAIL_OUT_ENOSPC     0x1704
21495         do_facet mds2 lctl set_param fail_loc=0x80001704
21496         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
21497                  && error "create striped directory should fail"
21498
21499         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
21500
21501         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
21502         true
21503 }
21504 run_test 300p "create striped directory without space"
21505
21506 test_300q() {
21507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21508         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21509
21510         local fd=$(free_fd)
21511         local cmd="exec $fd<$tdir"
21512         cd $DIR
21513         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
21514         eval $cmd
21515         cmd="exec $fd<&-"
21516         trap "eval $cmd" EXIT
21517         cd $tdir || error "cd $tdir fails"
21518         rmdir  ../$tdir || error "rmdir $tdir fails"
21519         mkdir local_dir && error "create dir succeeds"
21520         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
21521         eval $cmd
21522         return 0
21523 }
21524 run_test 300q "create remote directory under orphan directory"
21525
21526 test_300r() {
21527         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21528                 skip "Need MDS version at least 2.7.55" && return
21529         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21530
21531         mkdir $DIR/$tdir
21532
21533         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
21534                 error "set striped dir error"
21535
21536         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21537                 error "getstripeddir fails"
21538
21539         local stripe_count
21540         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
21541                       awk '/lmv_stripe_count:/ { print $2 }')
21542
21543         [ $MDSCOUNT -ne $stripe_count ] &&
21544                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
21545
21546         rm -rf $DIR/$tdir/striped_dir ||
21547                 error "unlink striped dir fails"
21548 }
21549 run_test 300r "test -1 striped directory"
21550
21551 prepare_remote_file() {
21552         mkdir $DIR/$tdir/src_dir ||
21553                 error "create remote source failed"
21554
21555         cp /etc/hosts $DIR/$tdir/src_dir/a ||
21556                  error "cp to remote source failed"
21557         touch $DIR/$tdir/src_dir/a
21558
21559         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
21560                 error "create remote target dir failed"
21561
21562         touch $DIR/$tdir/tgt_dir/b
21563
21564         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
21565                 error "rename dir cross MDT failed!"
21566
21567         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
21568                 error "src_child still exists after rename"
21569
21570         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
21571                 error "missing file(a) after rename"
21572
21573         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
21574                 error "diff after rename"
21575 }
21576
21577 test_310a() {
21578         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21580
21581         local remote_file=$DIR/$tdir/tgt_dir/b
21582
21583         mkdir -p $DIR/$tdir
21584
21585         prepare_remote_file || error "prepare remote file failed"
21586
21587         #open-unlink file
21588         $OPENUNLINK $remote_file $remote_file ||
21589                 error "openunlink $remote_file failed"
21590         $CHECKSTAT -a $remote_file || error "$remote_file exists"
21591 }
21592 run_test 310a "open unlink remote file"
21593
21594 test_310b() {
21595         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21597
21598         local remote_file=$DIR/$tdir/tgt_dir/b
21599
21600         mkdir -p $DIR/$tdir
21601
21602         prepare_remote_file || error "prepare remote file failed"
21603
21604         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21605         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
21606         $CHECKSTAT -t file $remote_file || error "check file failed"
21607 }
21608 run_test 310b "unlink remote file with multiple links while open"
21609
21610 test_310c() {
21611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21612         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
21613
21614         local remote_file=$DIR/$tdir/tgt_dir/b
21615
21616         mkdir -p $DIR/$tdir
21617
21618         prepare_remote_file || error "prepare remote file failed"
21619
21620         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21621         multiop_bg_pause $remote_file O_uc ||
21622                         error "mulitop failed for remote file"
21623         MULTIPID=$!
21624         $MULTIOP $DIR/$tfile Ouc
21625         kill -USR1 $MULTIPID
21626         wait $MULTIPID
21627 }
21628 run_test 310c "open-unlink remote file with multiple links"
21629
21630 #LU-4825
21631 test_311() {
21632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21633         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21634         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
21635                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
21636         remote_mds_nodsh && skip "remote MDS with nodsh"
21637
21638         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21639         local mdts=$(comma_list $(mdts_nodes))
21640
21641         mkdir -p $DIR/$tdir
21642         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21643         createmany -o $DIR/$tdir/$tfile. 1000
21644
21645         # statfs data is not real time, let's just calculate it
21646         old_iused=$((old_iused + 1000))
21647
21648         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21649                         osp.*OST0000*MDT0000.create_count")
21650         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21651                                 osp.*OST0000*MDT0000.max_create_count")
21652         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
21653
21654         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
21655         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
21656         [ $index -ne 0 ] || error "$tfile stripe index is 0"
21657
21658         unlinkmany $DIR/$tdir/$tfile. 1000
21659
21660         do_nodes $mdts "$LCTL set_param -n \
21661                         osp.*OST0000*.max_create_count=$max_count"
21662         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
21663                 do_nodes $mdts "$LCTL set_param -n \
21664                                 osp.*OST0000*.create_count=$count"
21665         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
21666                         grep "=0" && error "create_count is zero"
21667
21668         local new_iused
21669         for i in $(seq 120); do
21670                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21671                 # system may be too busy to destroy all objs in time, use
21672                 # a somewhat small value to not fail autotest
21673                 [ $((old_iused - new_iused)) -gt 400 ] && break
21674                 sleep 1
21675         done
21676
21677         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
21678         [ $((old_iused - new_iused)) -gt 400 ] ||
21679                 error "objs not destroyed after unlink"
21680 }
21681 run_test 311 "disable OSP precreate, and unlink should destroy objs"
21682
21683 zfs_oid_to_objid()
21684 {
21685         local ost=$1
21686         local objid=$2
21687
21688         local vdevdir=$(dirname $(facet_vdevice $ost))
21689         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
21690         local zfs_zapid=$(do_facet $ost $cmd |
21691                           grep -w "/O/0/d$((objid%32))" -C 5 |
21692                           awk '/Object/{getline; print $1}')
21693         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
21694                           awk "/$objid = /"'{printf $3}')
21695
21696         echo $zfs_objid
21697 }
21698
21699 zfs_object_blksz() {
21700         local ost=$1
21701         local objid=$2
21702
21703         local vdevdir=$(dirname $(facet_vdevice $ost))
21704         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
21705         local blksz=$(do_facet $ost $cmd $objid |
21706                       awk '/dblk/{getline; printf $4}')
21707
21708         case "${blksz: -1}" in
21709                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
21710                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
21711                 *) ;;
21712         esac
21713
21714         echo $blksz
21715 }
21716
21717 test_312() { # LU-4856
21718         remote_ost_nodsh && skip "remote OST with nodsh"
21719         [ "$ost1_FSTYPE" = "zfs" ] ||
21720                 skip_env "the test only applies to zfs"
21721
21722         local max_blksz=$(do_facet ost1 \
21723                           $ZFS get -p recordsize $(facet_device ost1) |
21724                           awk '!/VALUE/{print $3}')
21725
21726         # to make life a little bit easier
21727         $LFS mkdir -c 1 -i 0 $DIR/$tdir
21728         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21729
21730         local tf=$DIR/$tdir/$tfile
21731         touch $tf
21732         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21733
21734         # Get ZFS object id
21735         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21736         # block size change by sequential overwrite
21737         local bs
21738
21739         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
21740                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
21741
21742                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
21743                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
21744         done
21745         rm -f $tf
21746
21747         # block size change by sequential append write
21748         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
21749         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21750         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21751         local count
21752
21753         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
21754                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
21755                         oflag=sync conv=notrunc
21756
21757                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
21758                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
21759                         error "blksz error, actual $blksz, " \
21760                                 "expected: 2 * $count * $PAGE_SIZE"
21761         done
21762         rm -f $tf
21763
21764         # random write
21765         touch $tf
21766         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21767         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21768
21769         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
21770         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21771         [ $blksz -eq $PAGE_SIZE ] ||
21772                 error "blksz error: $blksz, expected: $PAGE_SIZE"
21773
21774         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
21775         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21776         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
21777
21778         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
21779         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21780         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
21781 }
21782 run_test 312 "make sure ZFS adjusts its block size by write pattern"
21783
21784 test_313() {
21785         remote_ost_nodsh && skip "remote OST with nodsh"
21786
21787         local file=$DIR/$tfile
21788
21789         rm -f $file
21790         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
21791
21792         # define OBD_FAIL_TGT_RCVD_EIO           0x720
21793         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21794         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
21795                 error "write should failed"
21796         do_facet ost1 "$LCTL set_param fail_loc=0"
21797         rm -f $file
21798 }
21799 run_test 313 "io should fail after last_rcvd update fail"
21800
21801 test_314() {
21802         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21803
21804         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
21805         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21806         rm -f $DIR/$tfile
21807         wait_delete_completed
21808         do_facet ost1 "$LCTL set_param fail_loc=0"
21809 }
21810 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
21811
21812 test_315() { # LU-618
21813         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
21814
21815         local file=$DIR/$tfile
21816         rm -f $file
21817
21818         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
21819                 error "multiop file write failed"
21820         $MULTIOP $file oO_RDONLY:r4063232_c &
21821         PID=$!
21822
21823         sleep 2
21824
21825         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
21826         kill -USR1 $PID
21827
21828         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
21829         rm -f $file
21830 }
21831 run_test 315 "read should be accounted"
21832
21833 test_316() {
21834         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21835         large_xattr_enabled || skip_env "ea_inode feature disabled"
21836
21837         rm -rf $DIR/$tdir/d
21838         mkdir -p $DIR/$tdir/d
21839         chown nobody $DIR/$tdir/d
21840         touch $DIR/$tdir/d/file
21841
21842         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
21843 }
21844 run_test 316 "lfs mv"
21845
21846 test_317() {
21847         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
21848                 skip "Need MDS version at least 2.11.53"
21849         if [ "$ost1_FSTYPE" == "zfs" ]; then
21850                 skip "LU-10370: no implementation for ZFS"
21851         fi
21852
21853         local trunc_sz
21854         local grant_blk_size
21855
21856         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
21857                         awk '/grant_block_size:/ { print $2; exit; }')
21858         #
21859         # Create File of size 5M. Truncate it to below size's and verify
21860         # blocks count.
21861         #
21862         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
21863                 error "Create file $DIR/$tfile failed"
21864         stack_trap "rm -f $DIR/$tfile" EXIT
21865
21866         for trunc_sz in 2097152 4097 4000 509 0; do
21867                 $TRUNCATE $DIR/$tfile $trunc_sz ||
21868                         error "truncate $tfile to $trunc_sz failed"
21869                 local sz=$(stat --format=%s $DIR/$tfile)
21870                 local blk=$(stat --format=%b $DIR/$tfile)
21871                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
21872                                      grant_blk_size) * 8))
21873
21874                 if [[ $blk -ne $trunc_blk ]]; then
21875                         $(which stat) $DIR/$tfile
21876                         error "Expected Block $trunc_blk got $blk for $tfile"
21877                 fi
21878
21879                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21880                         error "Expected Size $trunc_sz got $sz for $tfile"
21881         done
21882
21883         #
21884         # sparse file test
21885         # Create file with a hole and write actual two blocks. Block count
21886         # must be 16.
21887         #
21888         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
21889                 conv=fsync || error "Create file : $DIR/$tfile"
21890
21891         # Calculate the final truncate size.
21892         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
21893
21894         #
21895         # truncate to size $trunc_sz bytes. Strip the last block
21896         # The block count must drop to 8
21897         #
21898         $TRUNCATE $DIR/$tfile $trunc_sz ||
21899                 error "truncate $tfile to $trunc_sz failed"
21900
21901         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
21902         sz=$(stat --format=%s $DIR/$tfile)
21903         blk=$(stat --format=%b $DIR/$tfile)
21904
21905         if [[ $blk -ne $trunc_bsz ]]; then
21906                 $(which stat) $DIR/$tfile
21907                 error "Expected Block $trunc_bsz got $blk for $tfile"
21908         fi
21909
21910         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21911                 error "Expected Size $trunc_sz got $sz for $tfile"
21912 }
21913 run_test 317 "Verify blocks get correctly update after truncate"
21914
21915 test_318() {
21916         local old_max_active=$($LCTL get_param -n \
21917                             llite.*.max_read_ahead_async_active 2>/dev/null)
21918
21919         $LCTL set_param llite.*.max_read_ahead_async_active=256
21920         local max_active=$($LCTL get_param -n \
21921                            llite.*.max_read_ahead_async_active 2>/dev/null)
21922         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
21923
21924         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
21925                 error "set max_read_ahead_async_active should succeed"
21926
21927         $LCTL set_param llite.*.max_read_ahead_async_active=512
21928         max_active=$($LCTL get_param -n \
21929                      llite.*.max_read_ahead_async_active 2>/dev/null)
21930         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
21931
21932         # restore @max_active
21933         [ $old_max_active -ne 0 ] && $LCTL set_param \
21934                 llite.*.max_read_ahead_async_active=$old_max_active
21935
21936         local old_threshold=$($LCTL get_param -n \
21937                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21938         local max_per_file_mb=$($LCTL get_param -n \
21939                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
21940
21941         local invalid=$(($max_per_file_mb + 1))
21942         $LCTL set_param \
21943                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
21944                         && error "set $invalid should fail"
21945
21946         local valid=$(($invalid - 1))
21947         $LCTL set_param \
21948                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
21949                         error "set $valid should succeed"
21950         local threshold=$($LCTL get_param -n \
21951                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21952         [ $threshold -eq $valid ] || error \
21953                 "expect threshold $valid got $threshold"
21954         $LCTL set_param \
21955                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
21956 }
21957 run_test 318 "Verify async readahead tunables"
21958
21959 test_319() {
21960         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
21961
21962         local before=$(date +%s)
21963         local evict
21964         local mdir=$DIR/$tdir
21965         local file=$mdir/xxx
21966
21967         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
21968         touch $file
21969
21970 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
21971         $LCTL set_param fail_val=5 fail_loc=0x8000032c
21972         $LFS mv -m1 $file &
21973
21974         sleep 1
21975         dd if=$file of=/dev/null
21976         wait
21977         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
21978           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
21979
21980         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
21981 }
21982 run_test 319 "lost lease lock on migrate error"
21983
21984 test_398a() { # LU-4198
21985         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21986         $LCTL set_param ldlm.namespaces.*.lru_size=clear
21987
21988         # request a new lock on client
21989         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21990
21991         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21992         local lock_count=$($LCTL get_param -n \
21993                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21994         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
21995
21996         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
21997
21998         # no lock cached, should use lockless IO and not enqueue new lock
21999         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22000         lock_count=$($LCTL get_param -n \
22001                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22002         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
22003 }
22004 run_test 398a "direct IO should cancel lock otherwise lockless"
22005
22006 test_398b() { # LU-4198
22007         which fio || skip_env "no fio installed"
22008         $LFS setstripe -c -1 $DIR/$tfile
22009
22010         local size=12
22011         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
22012
22013         local njobs=4
22014         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
22015         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22016                 --numjobs=$njobs --fallocate=none \
22017                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22018                 --filename=$DIR/$tfile &
22019         bg_pid=$!
22020
22021         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
22022         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
22023                 --numjobs=$njobs --fallocate=none \
22024                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22025                 --filename=$DIR/$tfile || true
22026         wait $bg_pid
22027
22028         rm -rf $DIR/$tfile
22029 }
22030 run_test 398b "DIO and buffer IO race"
22031
22032 test_398c() { # LU-4198
22033         which fio || skip_env "no fio installed"
22034
22035         saved_debug=$($LCTL get_param -n debug)
22036         $LCTL set_param debug=0
22037
22038         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
22039         ((size /= 1024)) # by megabytes
22040         ((size /= 2)) # write half of the OST at most
22041         [ $size -gt 40 ] && size=40 #reduce test time anyway
22042
22043         $LFS setstripe -c 1 $DIR/$tfile
22044
22045         # it seems like ldiskfs reserves more space than necessary if the
22046         # writing blocks are not mapped, so it extends the file firstly
22047         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
22048         cancel_lru_locks osc
22049
22050         # clear and verify rpc_stats later
22051         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
22052
22053         local njobs=4
22054         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
22055         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
22056                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22057                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22058                 --filename=$DIR/$tfile
22059         [ $? -eq 0 ] || error "fio write error"
22060
22061         [ $($LCTL get_param -n \
22062          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
22063                 error "Locks were requested while doing AIO"
22064
22065         # get the percentage of 1-page I/O
22066         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
22067                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
22068                 awk '{print $7}')
22069         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
22070
22071         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
22072         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22073                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22074                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22075                 --filename=$DIR/$tfile
22076         [ $? -eq 0 ] || error "fio mixed read write error"
22077
22078         echo "AIO with large block size ${size}M"
22079         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
22080                 --numjobs=1 --fallocate=none --ioengine=libaio \
22081                 --iodepth=16 --allow_file_create=0 --size=${size}M \
22082                 --filename=$DIR/$tfile
22083         [ $? -eq 0 ] || error "fio large block size failed"
22084
22085         rm -rf $DIR/$tfile
22086         $LCTL set_param debug="$saved_debug"
22087 }
22088 run_test 398c "run fio to test AIO"
22089
22090 test_398d() { #  LU-13846
22091         test -f aiocp || skip_env "no aiocp installed"
22092         local aio_file=$DIR/aio_file
22093
22094         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
22095
22096         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
22097         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
22098
22099         diff $DIR/$tfile $aio_file || "file diff after aiocp"
22100
22101         # make sure we don't crash and fail properly
22102         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
22103                 error "aio not aligned with PAGE SIZE should fail"
22104
22105         rm -rf $DIR/$tfile $aio_file
22106 }
22107 run_test 398d "run aiocp to verify block size > stripe size"
22108
22109 test_fake_rw() {
22110         local read_write=$1
22111         if [ "$read_write" = "write" ]; then
22112                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
22113         elif [ "$read_write" = "read" ]; then
22114                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
22115         else
22116                 error "argument error"
22117         fi
22118
22119         # turn off debug for performance testing
22120         local saved_debug=$($LCTL get_param -n debug)
22121         $LCTL set_param debug=0
22122
22123         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22124
22125         # get ost1 size - $FSNAME-OST0000
22126         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
22127         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22128         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22129
22130         if [ "$read_write" = "read" ]; then
22131                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
22132         fi
22133
22134         local start_time=$(date +%s.%N)
22135         $dd_cmd bs=1M count=$blocks oflag=sync ||
22136                 error "real dd $read_write error"
22137         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22138
22139         if [ "$read_write" = "write" ]; then
22140                 rm -f $DIR/$tfile
22141         fi
22142
22143         # define OBD_FAIL_OST_FAKE_RW           0x238
22144         do_facet ost1 $LCTL set_param fail_loc=0x238
22145
22146         local start_time=$(date +%s.%N)
22147         $dd_cmd bs=1M count=$blocks oflag=sync ||
22148                 error "fake dd $read_write error"
22149         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22150
22151         if [ "$read_write" = "write" ]; then
22152                 # verify file size
22153                 cancel_lru_locks osc
22154                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22155                         error "$tfile size not $blocks MB"
22156         fi
22157         do_facet ost1 $LCTL set_param fail_loc=0
22158
22159         echo "fake $read_write $duration_fake vs. normal $read_write" \
22160                 "$duration in seconds"
22161         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22162                 error_not_in_vm "fake write is slower"
22163
22164         $LCTL set_param -n debug="$saved_debug"
22165         rm -f $DIR/$tfile
22166 }
22167 test_399a() { # LU-7655 for OST fake write
22168         remote_ost_nodsh && skip "remote OST with nodsh"
22169
22170         test_fake_rw write
22171 }
22172 run_test 399a "fake write should not be slower than normal write"
22173
22174 test_399b() { # LU-8726 for OST fake read
22175         remote_ost_nodsh && skip "remote OST with nodsh"
22176         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22177                 skip_env "ldiskfs only test"
22178         fi
22179
22180         test_fake_rw read
22181 }
22182 run_test 399b "fake read should not be slower than normal read"
22183
22184 test_400a() { # LU-1606, was conf-sanity test_74
22185         if ! which $CC > /dev/null 2>&1; then
22186                 skip_env "$CC is not installed"
22187         fi
22188
22189         local extra_flags=''
22190         local out=$TMP/$tfile
22191         local prefix=/usr/include/lustre
22192         local prog
22193
22194         # Oleg removes c files in his test rig so test if any c files exist
22195         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22196                 skip_env "Needed c test files are missing"
22197
22198         if ! [[ -d $prefix ]]; then
22199                 # Assume we're running in tree and fixup the include path.
22200                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22201                 extra_flags+=" -L$LUSTRE/utils/.lib"
22202         fi
22203
22204         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22205                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22206                         error "client api broken"
22207         done
22208         rm -f $out
22209 }
22210 run_test 400a "Lustre client api program can compile and link"
22211
22212 test_400b() { # LU-1606, LU-5011
22213         local header
22214         local out=$TMP/$tfile
22215         local prefix=/usr/include/linux/lustre
22216
22217         # We use a hard coded prefix so that this test will not fail
22218         # when run in tree. There are headers in lustre/include/lustre/
22219         # that are not packaged (like lustre_idl.h) and have more
22220         # complicated include dependencies (like config.h and lnet/types.h).
22221         # Since this test about correct packaging we just skip them when
22222         # they don't exist (see below) rather than try to fixup cppflags.
22223
22224         if ! which $CC > /dev/null 2>&1; then
22225                 skip_env "$CC is not installed"
22226         fi
22227
22228         for header in $prefix/*.h; do
22229                 if ! [[ -f "$header" ]]; then
22230                         continue
22231                 fi
22232
22233                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22234                         continue # lustre_ioctl.h is internal header
22235                 fi
22236
22237                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22238                         error "cannot compile '$header'"
22239         done
22240         rm -f $out
22241 }
22242 run_test 400b "packaged headers can be compiled"
22243
22244 test_401a() { #LU-7437
22245         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22246         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22247
22248         #count the number of parameters by "list_param -R"
22249         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22250         #count the number of parameters by listing proc files
22251         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22252         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22253         echo "proc_dirs='$proc_dirs'"
22254         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22255         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22256                       sort -u | wc -l)
22257
22258         [ $params -eq $procs ] ||
22259                 error "found $params parameters vs. $procs proc files"
22260
22261         # test the list_param -D option only returns directories
22262         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22263         #count the number of parameters by listing proc directories
22264         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22265                 sort -u | wc -l)
22266
22267         [ $params -eq $procs ] ||
22268                 error "found $params parameters vs. $procs proc files"
22269 }
22270 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22271
22272 test_401b() {
22273         # jobid_var may not allow arbitrary values, so use jobid_name
22274         # if available
22275         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22276                 local testname=jobid_name tmp='testing%p'
22277         else
22278                 local testname=jobid_var tmp=testing
22279         fi
22280
22281         local save=$($LCTL get_param -n $testname)
22282
22283         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
22284                 error "no error returned when setting bad parameters"
22285
22286         local jobid_new=$($LCTL get_param -n foe $testname baz)
22287         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22288
22289         $LCTL set_param -n fog=bam $testname=$save bat=fog
22290         local jobid_old=$($LCTL get_param -n foe $testname bag)
22291         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22292 }
22293 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22294
22295 test_401c() {
22296         # jobid_var may not allow arbitrary values, so use jobid_name
22297         # if available
22298         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22299                 local testname=jobid_name
22300         else
22301                 local testname=jobid_var
22302         fi
22303
22304         local jobid_var_old=$($LCTL get_param -n $testname)
22305         local jobid_var_new
22306
22307         $LCTL set_param $testname= &&
22308                 error "no error returned for 'set_param a='"
22309
22310         jobid_var_new=$($LCTL get_param -n $testname)
22311         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22312                 error "$testname was changed by setting without value"
22313
22314         $LCTL set_param $testname &&
22315                 error "no error returned for 'set_param a'"
22316
22317         jobid_var_new=$($LCTL get_param -n $testname)
22318         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22319                 error "$testname was changed by setting without value"
22320 }
22321 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22322
22323 test_401d() {
22324         # jobid_var may not allow arbitrary values, so use jobid_name
22325         # if available
22326         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22327                 local testname=jobid_name new_value='foo=bar%p'
22328         else
22329                 local testname=jobid_var new_valuie=foo=bar
22330         fi
22331
22332         local jobid_var_old=$($LCTL get_param -n $testname)
22333         local jobid_var_new
22334
22335         $LCTL set_param $testname=$new_value ||
22336                 error "'set_param a=b' did not accept a value containing '='"
22337
22338         jobid_var_new=$($LCTL get_param -n $testname)
22339         [[ "$jobid_var_new" == "$new_value" ]] ||
22340                 error "'set_param a=b' failed on a value containing '='"
22341
22342         # Reset the $testname to test the other format
22343         $LCTL set_param $testname=$jobid_var_old
22344         jobid_var_new=$($LCTL get_param -n $testname)
22345         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22346                 error "failed to reset $testname"
22347
22348         $LCTL set_param $testname $new_value ||
22349                 error "'set_param a b' did not accept a value containing '='"
22350
22351         jobid_var_new=$($LCTL get_param -n $testname)
22352         [[ "$jobid_var_new" == "$new_value" ]] ||
22353                 error "'set_param a b' failed on a value containing '='"
22354
22355         $LCTL set_param $testname $jobid_var_old
22356         jobid_var_new=$($LCTL get_param -n $testname)
22357         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22358                 error "failed to reset $testname"
22359 }
22360 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22361
22362 test_402() {
22363         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22364         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22365                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22366         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22367                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22368                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22369         remote_mds_nodsh && skip "remote MDS with nodsh"
22370
22371         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22372 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22373         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22374         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22375                 echo "Touch failed - OK"
22376 }
22377 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22378
22379 test_403() {
22380         local file1=$DIR/$tfile.1
22381         local file2=$DIR/$tfile.2
22382         local tfile=$TMP/$tfile
22383
22384         rm -f $file1 $file2 $tfile
22385
22386         touch $file1
22387         ln $file1 $file2
22388
22389         # 30 sec OBD_TIMEOUT in ll_getattr()
22390         # right before populating st_nlink
22391         $LCTL set_param fail_loc=0x80001409
22392         stat -c %h $file1 > $tfile &
22393
22394         # create an alias, drop all locks and reclaim the dentry
22395         < $file2
22396         cancel_lru_locks mdc
22397         cancel_lru_locks osc
22398         sysctl -w vm.drop_caches=2
22399
22400         wait
22401
22402         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
22403
22404         rm -f $tfile $file1 $file2
22405 }
22406 run_test 403 "i_nlink should not drop to zero due to aliasing"
22407
22408 test_404() { # LU-6601
22409         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
22410                 skip "Need server version newer than 2.8.52"
22411         remote_mds_nodsh && skip "remote MDS with nodsh"
22412
22413         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
22414                 awk '/osp .*-osc-MDT/ { print $4}')
22415
22416         local osp
22417         for osp in $mosps; do
22418                 echo "Deactivate: " $osp
22419                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22420                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22421                         awk -vp=$osp '$4 == p { print $2 }')
22422                 [ $stat = IN ] || {
22423                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22424                         error "deactivate error"
22425                 }
22426                 echo "Activate: " $osp
22427                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22428                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22429                         awk -vp=$osp '$4 == p { print $2 }')
22430                 [ $stat = UP ] || {
22431                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22432                         error "activate error"
22433                 }
22434         done
22435 }
22436 run_test 404 "validate manual {de}activated works properly for OSPs"
22437
22438 test_405() {
22439         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22440         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
22441                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
22442                         skip "Layout swap lock is not supported"
22443
22444         check_swap_layouts_support
22445         check_swap_layout_no_dom $DIR
22446
22447         test_mkdir $DIR/$tdir
22448         swap_lock_test -d $DIR/$tdir ||
22449                 error "One layout swap locked test failed"
22450 }
22451 run_test 405 "Various layout swap lock tests"
22452
22453 test_406() {
22454         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22455         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22456         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
22457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22458         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
22459                 skip "Need MDS version at least 2.8.50"
22460
22461         local def_stripe_size=$($LFS getstripe -S $MOUNT)
22462         local test_pool=$TESTNAME
22463
22464         pool_add $test_pool || error "pool_add failed"
22465         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
22466                 error "pool_add_targets failed"
22467
22468         save_layout_restore_at_exit $MOUNT
22469
22470         # parent set default stripe count only, child will stripe from both
22471         # parent and fs default
22472         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
22473                 error "setstripe $MOUNT failed"
22474         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22475         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
22476         for i in $(seq 10); do
22477                 local f=$DIR/$tdir/$tfile.$i
22478                 touch $f || error "touch failed"
22479                 local count=$($LFS getstripe -c $f)
22480                 [ $count -eq $OSTCOUNT ] ||
22481                         error "$f stripe count $count != $OSTCOUNT"
22482                 local offset=$($LFS getstripe -i $f)
22483                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
22484                 local size=$($LFS getstripe -S $f)
22485                 [ $size -eq $((def_stripe_size * 2)) ] ||
22486                         error "$f stripe size $size != $((def_stripe_size * 2))"
22487                 local pool=$($LFS getstripe -p $f)
22488                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
22489         done
22490
22491         # change fs default striping, delete parent default striping, now child
22492         # will stripe from new fs default striping only
22493         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
22494                 error "change $MOUNT default stripe failed"
22495         $LFS setstripe -c 0 $DIR/$tdir ||
22496                 error "delete $tdir default stripe failed"
22497         for i in $(seq 11 20); do
22498                 local f=$DIR/$tdir/$tfile.$i
22499                 touch $f || error "touch $f failed"
22500                 local count=$($LFS getstripe -c $f)
22501                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
22502                 local offset=$($LFS getstripe -i $f)
22503                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
22504                 local size=$($LFS getstripe -S $f)
22505                 [ $size -eq $def_stripe_size ] ||
22506                         error "$f stripe size $size != $def_stripe_size"
22507                 local pool=$($LFS getstripe -p $f)
22508                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
22509         done
22510
22511         unlinkmany $DIR/$tdir/$tfile. 1 20
22512
22513         local f=$DIR/$tdir/$tfile
22514         pool_remove_all_targets $test_pool $f
22515         pool_remove $test_pool $f
22516 }
22517 run_test 406 "DNE support fs default striping"
22518
22519 test_407() {
22520         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22521         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22522                 skip "Need MDS version at least 2.8.55"
22523         remote_mds_nodsh && skip "remote MDS with nodsh"
22524
22525         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
22526                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
22527         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
22528                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
22529         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
22530
22531         #define OBD_FAIL_DT_TXN_STOP    0x2019
22532         for idx in $(seq $MDSCOUNT); do
22533                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
22534         done
22535         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
22536         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
22537                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
22538         true
22539 }
22540 run_test 407 "transaction fail should cause operation fail"
22541
22542 test_408() {
22543         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
22544
22545         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
22546         lctl set_param fail_loc=0x8000040a
22547         # let ll_prepare_partial_page() fail
22548         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
22549
22550         rm -f $DIR/$tfile
22551
22552         # create at least 100 unused inodes so that
22553         # shrink_icache_memory(0) should not return 0
22554         touch $DIR/$tfile-{0..100}
22555         rm -f $DIR/$tfile-{0..100}
22556         sync
22557
22558         echo 2 > /proc/sys/vm/drop_caches
22559 }
22560 run_test 408 "drop_caches should not hang due to page leaks"
22561
22562 test_409()
22563 {
22564         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22565
22566         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
22567         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
22568         touch $DIR/$tdir/guard || error "(2) Fail to create"
22569
22570         local PREFIX=$(str_repeat 'A' 128)
22571         echo "Create 1K hard links start at $(date)"
22572         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22573                 error "(3) Fail to hard link"
22574
22575         echo "Links count should be right although linkEA overflow"
22576         stat $DIR/$tdir/guard || error "(4) Fail to stat"
22577         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
22578         [ $linkcount -eq 1001 ] ||
22579                 error "(5) Unexpected hard links count: $linkcount"
22580
22581         echo "List all links start at $(date)"
22582         ls -l $DIR/$tdir/foo > /dev/null ||
22583                 error "(6) Fail to list $DIR/$tdir/foo"
22584
22585         echo "Unlink hard links start at $(date)"
22586         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22587                 error "(7) Fail to unlink"
22588         echo "Unlink hard links finished at $(date)"
22589 }
22590 run_test 409 "Large amount of cross-MDTs hard links on the same file"
22591
22592 test_410()
22593 {
22594         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
22595                 skip "Need client version at least 2.9.59"
22596         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
22597                 skip "Need MODULES build"
22598
22599         # Create a file, and stat it from the kernel
22600         local testfile=$DIR/$tfile
22601         touch $testfile
22602
22603         local run_id=$RANDOM
22604         local my_ino=$(stat --format "%i" $testfile)
22605
22606         # Try to insert the module. This will always fail as the
22607         # module is designed to not be inserted.
22608         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
22609             &> /dev/null
22610
22611         # Anything but success is a test failure
22612         dmesg | grep -q \
22613             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
22614             error "no inode match"
22615 }
22616 run_test 410 "Test inode number returned from kernel thread"
22617
22618 cleanup_test411_cgroup() {
22619         trap 0
22620         rmdir "$1"
22621 }
22622
22623 test_411() {
22624         local cg_basedir=/sys/fs/cgroup/memory
22625         # LU-9966
22626         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
22627                 skip "no setup for cgroup"
22628
22629         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
22630                 error "test file creation failed"
22631         cancel_lru_locks osc
22632
22633         # Create a very small memory cgroup to force a slab allocation error
22634         local cgdir=$cg_basedir/osc_slab_alloc
22635         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
22636         trap "cleanup_test411_cgroup $cgdir" EXIT
22637         echo 2M > $cgdir/memory.kmem.limit_in_bytes
22638         echo 1M > $cgdir/memory.limit_in_bytes
22639
22640         # Should not LBUG, just be killed by oom-killer
22641         # dd will return 0 even allocation failure in some environment.
22642         # So don't check return value
22643         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
22644         cleanup_test411_cgroup $cgdir
22645
22646         return 0
22647 }
22648 run_test 411 "Slab allocation error with cgroup does not LBUG"
22649
22650 test_412() {
22651         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22652         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
22653                 skip "Need server version at least 2.10.55"
22654         fi
22655
22656         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
22657                 error "mkdir failed"
22658         $LFS getdirstripe $DIR/$tdir
22659         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22660         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
22661                 error "expect $((MDSCOUT - 1)) get $stripe_index"
22662         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
22663         [ $stripe_count -eq 2 ] ||
22664                 error "expect 2 get $stripe_count"
22665 }
22666 run_test 412 "mkdir on specific MDTs"
22667
22668 test_qos_mkdir() {
22669         local mkdir_cmd=$1
22670         local stripe_count=$2
22671         local mdts=$(comma_list $(mdts_nodes))
22672
22673         local testdir
22674         local lmv_qos_prio_free
22675         local lmv_qos_threshold_rr
22676         local lmv_qos_maxage
22677         local lod_qos_prio_free
22678         local lod_qos_threshold_rr
22679         local lod_qos_maxage
22680         local count
22681         local i
22682
22683         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
22684         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
22685         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
22686                 head -n1)
22687         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
22688         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
22689         stack_trap "$LCTL set_param \
22690                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
22691         stack_trap "$LCTL set_param \
22692                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
22693         stack_trap "$LCTL set_param \
22694                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
22695
22696         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
22697                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
22698         lod_qos_prio_free=${lod_qos_prio_free%%%}
22699         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
22700                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
22701         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
22702         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
22703                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
22704         stack_trap "do_nodes $mdts $LCTL set_param \
22705                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
22706         stack_trap "do_nodes $mdts $LCTL set_param \
22707                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
22708                 EXIT
22709         stack_trap "do_nodes $mdts $LCTL set_param \
22710                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
22711
22712         echo
22713         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
22714
22715         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
22716         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
22717
22718         testdir=$DIR/$tdir-s$stripe_count/rr
22719
22720         for i in $(seq $((100 * MDSCOUNT))); do
22721                 eval $mkdir_cmd $testdir/subdir$i ||
22722                         error "$mkdir_cmd subdir$i failed"
22723         done
22724
22725         for i in $(seq $MDSCOUNT); do
22726                 count=$($LFS getdirstripe -i $testdir/* |
22727                                 grep ^$((i - 1))$ | wc -l)
22728                 echo "$count directories created on MDT$((i - 1))"
22729                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
22730
22731                 if [ $stripe_count -gt 1 ]; then
22732                         count=$($LFS getdirstripe $testdir/* |
22733                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22734                         echo "$count stripes created on MDT$((i - 1))"
22735                         # deviation should < 5% of average
22736                         [ $count -lt $((95 * stripe_count)) ] ||
22737                         [ $count -gt $((105 * stripe_count)) ] &&
22738                                 error "stripes are not evenly distributed"
22739                 fi
22740         done
22741
22742         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
22743         do_nodes $mdts $LCTL set_param \
22744                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
22745
22746         echo
22747         echo "Check for uneven MDTs: "
22748
22749         local ffree
22750         local bavail
22751         local max
22752         local min
22753         local max_index
22754         local min_index
22755         local tmp
22756
22757         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
22758         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
22759         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
22760
22761         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22762         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22763         max_index=0
22764         min_index=0
22765         for ((i = 1; i < ${#ffree[@]}; i++)); do
22766                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
22767                 if [ $tmp -gt $max ]; then
22768                         max=$tmp
22769                         max_index=$i
22770                 fi
22771                 if [ $tmp -lt $min ]; then
22772                         min=$tmp
22773                         min_index=$i
22774                 fi
22775         done
22776
22777         [ ${ffree[min_index]} -eq 0 ] &&
22778                 skip "no free files in MDT$min_index"
22779         [ ${ffree[min_index]} -gt 100000000 ] &&
22780                 skip "too much free files in MDT$min_index"
22781
22782         # Check if we need to generate uneven MDTs
22783         local threshold=50
22784         local diff=$(((max - min) * 100 / min))
22785         local value="$(generate_string 1024)"
22786
22787         while [ $diff -lt $threshold ]; do
22788                 # generate uneven MDTs, create till $threshold% diff
22789                 echo -n "weight diff=$diff% must be > $threshold% ..."
22790                 count=$((${ffree[min_index]} / 10))
22791                 # 50 sec per 10000 files in vm
22792                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
22793                         skip "$count files to create"
22794                 echo "Fill MDT$min_index with $count files"
22795                 [ -d $DIR/$tdir-MDT$min_index ] ||
22796                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
22797                         error "mkdir $tdir-MDT$min_index failed"
22798                 for i in $(seq $count); do
22799                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
22800                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
22801                                 error "create f$j_$i failed"
22802                         setfattr -n user.413b -v $value \
22803                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
22804                                 error "setfattr f$j_$i failed"
22805                 done
22806
22807                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
22808                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
22809                 max=$(((${ffree[max_index]} >> 8) * \
22810                         (${bavail[max_index]} * bsize >> 16)))
22811                 min=$(((${ffree[min_index]} >> 8) * \
22812                         (${bavail[min_index]} * bsize >> 16)))
22813                 diff=$(((max - min) * 100 / min))
22814         done
22815
22816         echo "MDT filesfree available: ${ffree[@]}"
22817         echo "MDT blocks available: ${bavail[@]}"
22818         echo "weight diff=$diff%"
22819
22820         echo
22821         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
22822
22823         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
22824         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
22825         # decrease statfs age, so that it can be updated in time
22826         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
22827         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
22828
22829         sleep 1
22830
22831         testdir=$DIR/$tdir-s$stripe_count/qos
22832
22833         for i in $(seq $((100 * MDSCOUNT))); do
22834                 eval $mkdir_cmd $testdir/subdir$i ||
22835                         error "$mkdir_cmd subdir$i failed"
22836         done
22837
22838         for i in $(seq $MDSCOUNT); do
22839                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
22840                         wc -l)
22841                 echo "$count directories created on MDT$((i - 1))"
22842
22843                 if [ $stripe_count -gt 1 ]; then
22844                         count=$($LFS getdirstripe $testdir/* |
22845                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22846                         echo "$count stripes created on MDT$((i - 1))"
22847                 fi
22848         done
22849
22850         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
22851         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
22852
22853         # D-value should > 10% of averge
22854         [ $((max - min)) -lt 10 ] &&
22855                 error "subdirs shouldn't be evenly distributed"
22856
22857         # ditto
22858         if [ $stripe_count -gt 1 ]; then
22859                 max=$($LFS getdirstripe $testdir/* |
22860                         grep -P "^\s+$max_index\t" | wc -l)
22861                 min=$($LFS getdirstripe $testdir/* |
22862                         grep -P "^\s+$min_index\t" | wc -l)
22863                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
22864                         error "stripes shouldn't be evenly distributed"|| true
22865         fi
22866 }
22867
22868 test_413a() {
22869         [ $MDSCOUNT -lt 2 ] &&
22870                 skip "We need at least 2 MDTs for this test"
22871
22872         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22873                 skip "Need server version at least 2.12.52"
22874
22875         local stripe_count
22876
22877         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22878                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22879                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22880                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22881                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
22882         done
22883 }
22884 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
22885
22886 test_413b() {
22887         [ $MDSCOUNT -lt 2 ] &&
22888                 skip "We need at least 2 MDTs for this test"
22889
22890         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22891                 skip "Need server version at least 2.12.52"
22892
22893         local stripe_count
22894
22895         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22896                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22897                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22898                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22899                 $LFS setdirstripe -D -c $stripe_count \
22900                         $DIR/$tdir-s$stripe_count/rr ||
22901                         error "setdirstripe failed"
22902                 $LFS setdirstripe -D -c $stripe_count \
22903                         $DIR/$tdir-s$stripe_count/qos ||
22904                         error "setdirstripe failed"
22905                 test_qos_mkdir "mkdir" $stripe_count
22906         done
22907 }
22908 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
22909
22910 test_414() {
22911 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
22912         $LCTL set_param fail_loc=0x80000521
22913         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
22914         rm -f $DIR/$tfile
22915 }
22916 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
22917
22918 test_415() {
22919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22920         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22921                 skip "Need server version at least 2.11.52"
22922
22923         # LU-11102
22924         local total
22925         local setattr_pid
22926         local start_time
22927         local end_time
22928         local duration
22929
22930         total=500
22931         # this test may be slow on ZFS
22932         [ "$mds1_FSTYPE" == "zfs" ] && total=100
22933
22934         # though this test is designed for striped directory, let's test normal
22935         # directory too since lock is always saved as CoS lock.
22936         test_mkdir $DIR/$tdir || error "mkdir $tdir"
22937         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
22938
22939         (
22940                 while true; do
22941                         touch $DIR/$tdir
22942                 done
22943         ) &
22944         setattr_pid=$!
22945
22946         start_time=$(date +%s)
22947         for i in $(seq $total); do
22948                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
22949                         > /dev/null
22950         done
22951         end_time=$(date +%s)
22952         duration=$((end_time - start_time))
22953
22954         kill -9 $setattr_pid
22955
22956         echo "rename $total files took $duration sec"
22957         [ $duration -lt 100 ] || error "rename took $duration sec"
22958 }
22959 run_test 415 "lock revoke is not missing"
22960
22961 test_416() {
22962         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
22963                 skip "Need server version at least 2.11.55"
22964
22965         # define OBD_FAIL_OSD_TXN_START    0x19a
22966         do_facet mds1 lctl set_param fail_loc=0x19a
22967
22968         lfs mkdir -c $MDSCOUNT $DIR/$tdir
22969
22970         true
22971 }
22972 run_test 416 "transaction start failure won't cause system hung"
22973
22974 cleanup_417() {
22975         trap 0
22976         do_nodes $(comma_list $(mdts_nodes)) \
22977                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
22978         do_nodes $(comma_list $(mdts_nodes)) \
22979                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
22980         do_nodes $(comma_list $(mdts_nodes)) \
22981                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
22982 }
22983
22984 test_417() {
22985         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22986         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
22987                 skip "Need MDS version at least 2.11.56"
22988
22989         trap cleanup_417 RETURN EXIT
22990
22991         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
22992         do_nodes $(comma_list $(mdts_nodes)) \
22993                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
22994         $LFS migrate -m 0 $DIR/$tdir.1 &&
22995                 error "migrate dir $tdir.1 should fail"
22996
22997         do_nodes $(comma_list $(mdts_nodes)) \
22998                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
22999         $LFS mkdir -i 1 $DIR/$tdir.2 &&
23000                 error "create remote dir $tdir.2 should fail"
23001
23002         do_nodes $(comma_list $(mdts_nodes)) \
23003                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
23004         $LFS mkdir -c 2 $DIR/$tdir.3 &&
23005                 error "create striped dir $tdir.3 should fail"
23006         true
23007 }
23008 run_test 417 "disable remote dir, striped dir and dir migration"
23009
23010 # Checks that the outputs of df [-i] and lfs df [-i] match
23011 #
23012 # usage: check_lfs_df <blocks | inodes> <mountpoint>
23013 check_lfs_df() {
23014         local dir=$2
23015         local inodes
23016         local df_out
23017         local lfs_df_out
23018         local count
23019         local passed=false
23020
23021         # blocks or inodes
23022         [ "$1" == "blocks" ] && inodes= || inodes="-i"
23023
23024         for count in {1..100}; do
23025                 cancel_lru_locks
23026                 sync; sleep 0.2
23027
23028                 # read the lines of interest
23029                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
23030                         error "df $inodes $dir | tail -n +2 failed"
23031                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
23032                         error "lfs df $inodes $dir | grep summary: failed"
23033
23034                 # skip first substrings of each output as they are different
23035                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
23036                 # compare the two outputs
23037                 passed=true
23038                 for i in {1..5}; do
23039                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
23040                 done
23041                 $passed && break
23042         done
23043
23044         if ! $passed; then
23045                 df -P $inodes $dir
23046                 echo
23047                 lfs df $inodes $dir
23048                 error "df and lfs df $1 output mismatch: "      \
23049                       "df ${inodes}: ${df_out[*]}, "            \
23050                       "lfs df ${inodes}: ${lfs_df_out[*]}"
23051         fi
23052 }
23053
23054 test_418() {
23055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23056
23057         local dir=$DIR/$tdir
23058         local numfiles=$((RANDOM % 4096 + 2))
23059         local numblocks=$((RANDOM % 256 + 1))
23060
23061         wait_delete_completed
23062         test_mkdir $dir
23063
23064         # check block output
23065         check_lfs_df blocks $dir
23066         # check inode output
23067         check_lfs_df inodes $dir
23068
23069         # create a single file and retest
23070         echo "Creating a single file and testing"
23071         createmany -o $dir/$tfile- 1 &>/dev/null ||
23072                 error "creating 1 file in $dir failed"
23073         check_lfs_df blocks $dir
23074         check_lfs_df inodes $dir
23075
23076         # create a random number of files
23077         echo "Creating $((numfiles - 1)) files and testing"
23078         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
23079                 error "creating $((numfiles - 1)) files in $dir failed"
23080
23081         # write a random number of blocks to the first test file
23082         echo "Writing $numblocks 4K blocks and testing"
23083         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
23084                 count=$numblocks &>/dev/null ||
23085                 error "dd to $dir/${tfile}-0 failed"
23086
23087         # retest
23088         check_lfs_df blocks $dir
23089         check_lfs_df inodes $dir
23090
23091         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
23092                 error "unlinking $numfiles files in $dir failed"
23093 }
23094 run_test 418 "df and lfs df outputs match"
23095
23096 test_419()
23097 {
23098         local dir=$DIR/$tdir
23099
23100         mkdir -p $dir
23101         touch $dir/file
23102
23103         cancel_lru_locks mdc
23104
23105         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
23106         $LCTL set_param fail_loc=0x1410
23107         cat $dir/file
23108         $LCTL set_param fail_loc=0
23109         rm -rf $dir
23110 }
23111 run_test 419 "Verify open file by name doesn't crash kernel"
23112
23113 test_420()
23114 {
23115         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
23116                 skip "Need MDS version at least 2.12.53"
23117
23118         local SAVE_UMASK=$(umask)
23119         local dir=$DIR/$tdir
23120         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
23121
23122         mkdir -p $dir
23123         umask 0000
23124         mkdir -m03777 $dir/testdir
23125         ls -dn $dir/testdir
23126         # Need to remove trailing '.' when SELinux is enabled
23127         local dirperms=$(ls -dn $dir/testdir |
23128                          awk '{ sub(/\.$/, "", $1); print $1}')
23129         [ $dirperms == "drwxrwsrwt" ] ||
23130                 error "incorrect perms on $dir/testdir"
23131
23132         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
23133                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
23134         ls -n $dir/testdir/testfile
23135         local fileperms=$(ls -n $dir/testdir/testfile |
23136                           awk '{ sub(/\.$/, "", $1); print $1}')
23137         [ $fileperms == "-rwxr-xr-x" ] ||
23138                 error "incorrect perms on $dir/testdir/testfile"
23139
23140         umask $SAVE_UMASK
23141 }
23142 run_test 420 "clear SGID bit on non-directories for non-members"
23143
23144 test_421a() {
23145         local cnt
23146         local fid1
23147         local fid2
23148
23149         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23150                 skip "Need MDS version at least 2.12.54"
23151
23152         test_mkdir $DIR/$tdir
23153         createmany -o $DIR/$tdir/f 3
23154         cnt=$(ls -1 $DIR/$tdir | wc -l)
23155         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23156
23157         fid1=$(lfs path2fid $DIR/$tdir/f1)
23158         fid2=$(lfs path2fid $DIR/$tdir/f2)
23159         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23160
23161         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23162         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23163
23164         cnt=$(ls -1 $DIR/$tdir | wc -l)
23165         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23166
23167         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23168         createmany -o $DIR/$tdir/f 3
23169         cnt=$(ls -1 $DIR/$tdir | wc -l)
23170         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23171
23172         fid1=$(lfs path2fid $DIR/$tdir/f1)
23173         fid2=$(lfs path2fid $DIR/$tdir/f2)
23174         echo "remove using fsname $FSNAME"
23175         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23176
23177         cnt=$(ls -1 $DIR/$tdir | wc -l)
23178         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23179 }
23180 run_test 421a "simple rm by fid"
23181
23182 test_421b() {
23183         local cnt
23184         local FID1
23185         local FID2
23186
23187         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23188                 skip "Need MDS version at least 2.12.54"
23189
23190         test_mkdir $DIR/$tdir
23191         createmany -o $DIR/$tdir/f 3
23192         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23193         MULTIPID=$!
23194
23195         FID1=$(lfs path2fid $DIR/$tdir/f1)
23196         FID2=$(lfs path2fid $DIR/$tdir/f2)
23197         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23198
23199         kill -USR1 $MULTIPID
23200         wait
23201
23202         cnt=$(ls $DIR/$tdir | wc -l)
23203         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23204 }
23205 run_test 421b "rm by fid on open file"
23206
23207 test_421c() {
23208         local cnt
23209         local FIDS
23210
23211         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23212                 skip "Need MDS version at least 2.12.54"
23213
23214         test_mkdir $DIR/$tdir
23215         createmany -o $DIR/$tdir/f 3
23216         touch $DIR/$tdir/$tfile
23217         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23218         cnt=$(ls -1 $DIR/$tdir | wc -l)
23219         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23220
23221         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23222         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23223
23224         cnt=$(ls $DIR/$tdir | wc -l)
23225         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23226 }
23227 run_test 421c "rm by fid against hardlinked files"
23228
23229 test_421d() {
23230         local cnt
23231         local FIDS
23232
23233         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23234                 skip "Need MDS version at least 2.12.54"
23235
23236         test_mkdir $DIR/$tdir
23237         createmany -o $DIR/$tdir/f 4097
23238         cnt=$(ls -1 $DIR/$tdir | wc -l)
23239         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23240
23241         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23242         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23243
23244         cnt=$(ls $DIR/$tdir | wc -l)
23245         rm -rf $DIR/$tdir
23246         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23247 }
23248 run_test 421d "rmfid en masse"
23249
23250 test_421e() {
23251         local cnt
23252         local FID
23253
23254         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23255         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23256                 skip "Need MDS version at least 2.12.54"
23257
23258         mkdir -p $DIR/$tdir
23259         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23260         createmany -o $DIR/$tdir/striped_dir/f 512
23261         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23262         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23263
23264         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23265                 sed "s/[/][^:]*://g")
23266         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23267
23268         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23269         rm -rf $DIR/$tdir
23270         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23271 }
23272 run_test 421e "rmfid in DNE"
23273
23274 test_421f() {
23275         local cnt
23276         local FID
23277
23278         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23279                 skip "Need MDS version at least 2.12.54"
23280
23281         test_mkdir $DIR/$tdir
23282         touch $DIR/$tdir/f
23283         cnt=$(ls -1 $DIR/$tdir | wc -l)
23284         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23285
23286         FID=$(lfs path2fid $DIR/$tdir/f)
23287         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23288         # rmfid should fail
23289         cnt=$(ls -1 $DIR/$tdir | wc -l)
23290         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23291
23292         chmod a+rw $DIR/$tdir
23293         ls -la $DIR/$tdir
23294         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23295         # rmfid should fail
23296         cnt=$(ls -1 $DIR/$tdir | wc -l)
23297         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23298
23299         rm -f $DIR/$tdir/f
23300         $RUNAS touch $DIR/$tdir/f
23301         FID=$(lfs path2fid $DIR/$tdir/f)
23302         echo "rmfid as root"
23303         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23304         cnt=$(ls -1 $DIR/$tdir | wc -l)
23305         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23306
23307         rm -f $DIR/$tdir/f
23308         $RUNAS touch $DIR/$tdir/f
23309         cnt=$(ls -1 $DIR/$tdir | wc -l)
23310         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23311         FID=$(lfs path2fid $DIR/$tdir/f)
23312         # rmfid w/o user_fid2path mount option should fail
23313         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23314         cnt=$(ls -1 $DIR/$tdir | wc -l)
23315         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23316
23317         umount_client $MOUNT || error "failed to umount client"
23318         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23319                 error "failed to mount client'"
23320
23321         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23322         # rmfid should succeed
23323         cnt=$(ls -1 $DIR/$tdir | wc -l)
23324         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23325
23326         # rmfid shouldn't allow to remove files due to dir's permission
23327         chmod a+rwx $DIR/$tdir
23328         touch $DIR/$tdir/f
23329         ls -la $DIR/$tdir
23330         FID=$(lfs path2fid $DIR/$tdir/f)
23331         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23332
23333         umount_client $MOUNT || error "failed to umount client"
23334         mount_client $MOUNT "$MOUNT_OPTS" ||
23335                 error "failed to mount client'"
23336
23337 }
23338 run_test 421f "rmfid checks permissions"
23339
23340 test_421g() {
23341         local cnt
23342         local FIDS
23343
23344         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23345         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23346                 skip "Need MDS version at least 2.12.54"
23347
23348         mkdir -p $DIR/$tdir
23349         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23350         createmany -o $DIR/$tdir/striped_dir/f 512
23351         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23352         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23353
23354         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23355                 sed "s/[/][^:]*://g")
23356
23357         rm -f $DIR/$tdir/striped_dir/f1*
23358         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23359         removed=$((512 - cnt))
23360
23361         # few files have been just removed, so we expect
23362         # rmfid to fail on their fids
23363         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23364         [ $removed != $errors ] && error "$errors != $removed"
23365
23366         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23367         rm -rf $DIR/$tdir
23368         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23369 }
23370 run_test 421g "rmfid to return errors properly"
23371
23372 test_422() {
23373         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23374         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23375         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23376         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23377         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23378
23379         local amc=$(at_max_get client)
23380         local amo=$(at_max_get mds1)
23381         local timeout=`lctl get_param -n timeout`
23382
23383         at_max_set 0 client
23384         at_max_set 0 mds1
23385
23386 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23387         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23388                         fail_val=$(((2*timeout + 10)*1000))
23389         touch $DIR/$tdir/d3/file &
23390         sleep 2
23391 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23392         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23393                         fail_val=$((2*timeout + 5))
23394         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23395         local pid=$!
23396         sleep 1
23397         kill -9 $pid
23398         sleep $((2 * timeout))
23399         echo kill $pid
23400         kill -9 $pid
23401         lctl mark touch
23402         touch $DIR/$tdir/d2/file3
23403         touch $DIR/$tdir/d2/file4
23404         touch $DIR/$tdir/d2/file5
23405
23406         wait
23407         at_max_set $amc client
23408         at_max_set $amo mds1
23409
23410         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
23411         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
23412                 error "Watchdog is always throttled"
23413 }
23414 run_test 422 "kill a process with RPC in progress"
23415
23416 stat_test() {
23417     df -h $MOUNT &
23418     df -h $MOUNT &
23419     df -h $MOUNT &
23420     df -h $MOUNT &
23421     df -h $MOUNT &
23422     df -h $MOUNT &
23423 }
23424
23425 test_423() {
23426     local _stats
23427     # ensure statfs cache is expired
23428     sleep 2;
23429
23430     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23431     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23432
23433     return 0
23434 }
23435 run_test 423 "statfs should return a right data"
23436
23437 test_424() {
23438 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
23439         $LCTL set_param fail_loc=0x80000522
23440         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23441         rm -f $DIR/$tfile
23442 }
23443 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
23444
23445 test_425() {
23446         test_mkdir -c -1 $DIR/$tdir
23447         $LFS setstripe -c -1 $DIR/$tdir
23448
23449         lru_resize_disable "" 100
23450         stack_trap "lru_resize_enable" EXIT
23451
23452         sleep 5
23453
23454         for i in $(seq $((MDSCOUNT * 125))); do
23455                 local t=$DIR/$tdir/$tfile_$i
23456
23457                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
23458                         error_noexit "Create file $t"
23459         done
23460         stack_trap "rm -rf $DIR/$tdir" EXIT
23461
23462         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
23463                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
23464                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
23465
23466                 [ $lock_count -le $lru_size ] ||
23467                         error "osc lock count $lock_count > lru size $lru_size"
23468         done
23469
23470         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
23471                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
23472                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
23473
23474                 [ $lock_count -le $lru_size ] ||
23475                         error "mdc lock count $lock_count > lru size $lru_size"
23476         done
23477 }
23478 run_test 425 "lock count should not exceed lru size"
23479
23480 test_426() {
23481         splice-test -r $DIR/$tfile
23482         splice-test -rd $DIR/$tfile
23483         splice-test $DIR/$tfile
23484         splice-test -d $DIR/$tfile
23485 }
23486 run_test 426 "splice test on Lustre"
23487
23488 prep_801() {
23489         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23490         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23491                 skip "Need server version at least 2.9.55"
23492
23493         start_full_debug_logging
23494 }
23495
23496 post_801() {
23497         stop_full_debug_logging
23498 }
23499
23500 barrier_stat() {
23501         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23502                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23503                            awk '/The barrier for/ { print $7 }')
23504                 echo $st
23505         else
23506                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
23507                 echo \'$st\'
23508         fi
23509 }
23510
23511 barrier_expired() {
23512         local expired
23513
23514         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23515                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23516                           awk '/will be expired/ { print $7 }')
23517         else
23518                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
23519         fi
23520
23521         echo $expired
23522 }
23523
23524 test_801a() {
23525         prep_801
23526
23527         echo "Start barrier_freeze at: $(date)"
23528         #define OBD_FAIL_BARRIER_DELAY          0x2202
23529         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23530         # Do not reduce barrier time - See LU-11873
23531         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
23532
23533         sleep 2
23534         local b_status=$(barrier_stat)
23535         echo "Got barrier status at: $(date)"
23536         [ "$b_status" = "'freezing_p1'" ] ||
23537                 error "(1) unexpected barrier status $b_status"
23538
23539         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23540         wait
23541         b_status=$(barrier_stat)
23542         [ "$b_status" = "'frozen'" ] ||
23543                 error "(2) unexpected barrier status $b_status"
23544
23545         local expired=$(barrier_expired)
23546         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
23547         sleep $((expired + 3))
23548
23549         b_status=$(barrier_stat)
23550         [ "$b_status" = "'expired'" ] ||
23551                 error "(3) unexpected barrier status $b_status"
23552
23553         # Do not reduce barrier time - See LU-11873
23554         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
23555                 error "(4) fail to freeze barrier"
23556
23557         b_status=$(barrier_stat)
23558         [ "$b_status" = "'frozen'" ] ||
23559                 error "(5) unexpected barrier status $b_status"
23560
23561         echo "Start barrier_thaw at: $(date)"
23562         #define OBD_FAIL_BARRIER_DELAY          0x2202
23563         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23564         do_facet mgs $LCTL barrier_thaw $FSNAME &
23565
23566         sleep 2
23567         b_status=$(barrier_stat)
23568         echo "Got barrier status at: $(date)"
23569         [ "$b_status" = "'thawing'" ] ||
23570                 error "(6) unexpected barrier status $b_status"
23571
23572         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23573         wait
23574         b_status=$(barrier_stat)
23575         [ "$b_status" = "'thawed'" ] ||
23576                 error "(7) unexpected barrier status $b_status"
23577
23578         #define OBD_FAIL_BARRIER_FAILURE        0x2203
23579         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
23580         do_facet mgs $LCTL barrier_freeze $FSNAME
23581
23582         b_status=$(barrier_stat)
23583         [ "$b_status" = "'failed'" ] ||
23584                 error "(8) unexpected barrier status $b_status"
23585
23586         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23587         do_facet mgs $LCTL barrier_thaw $FSNAME
23588
23589         post_801
23590 }
23591 run_test 801a "write barrier user interfaces and stat machine"
23592
23593 test_801b() {
23594         prep_801
23595
23596         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23597         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
23598         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
23599         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
23600         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
23601
23602         cancel_lru_locks mdc
23603
23604         # 180 seconds should be long enough
23605         do_facet mgs $LCTL barrier_freeze $FSNAME 180
23606
23607         local b_status=$(barrier_stat)
23608         [ "$b_status" = "'frozen'" ] ||
23609                 error "(6) unexpected barrier status $b_status"
23610
23611         mkdir $DIR/$tdir/d0/d10 &
23612         mkdir_pid=$!
23613
23614         touch $DIR/$tdir/d1/f13 &
23615         touch_pid=$!
23616
23617         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
23618         ln_pid=$!
23619
23620         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
23621         mv_pid=$!
23622
23623         rm -f $DIR/$tdir/d4/f12 &
23624         rm_pid=$!
23625
23626         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
23627
23628         # To guarantee taht the 'stat' is not blocked
23629         b_status=$(barrier_stat)
23630         [ "$b_status" = "'frozen'" ] ||
23631                 error "(8) unexpected barrier status $b_status"
23632
23633         # let above commands to run at background
23634         sleep 5
23635
23636         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
23637         ps -p $touch_pid || error "(10) touch should be blocked"
23638         ps -p $ln_pid || error "(11) link should be blocked"
23639         ps -p $mv_pid || error "(12) rename should be blocked"
23640         ps -p $rm_pid || error "(13) unlink should be blocked"
23641
23642         b_status=$(barrier_stat)
23643         [ "$b_status" = "'frozen'" ] ||
23644                 error "(14) unexpected barrier status $b_status"
23645
23646         do_facet mgs $LCTL barrier_thaw $FSNAME
23647         b_status=$(barrier_stat)
23648         [ "$b_status" = "'thawed'" ] ||
23649                 error "(15) unexpected barrier status $b_status"
23650
23651         wait $mkdir_pid || error "(16) mkdir should succeed"
23652         wait $touch_pid || error "(17) touch should succeed"
23653         wait $ln_pid || error "(18) link should succeed"
23654         wait $mv_pid || error "(19) rename should succeed"
23655         wait $rm_pid || error "(20) unlink should succeed"
23656
23657         post_801
23658 }
23659 run_test 801b "modification will be blocked by write barrier"
23660
23661 test_801c() {
23662         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23663
23664         prep_801
23665
23666         stop mds2 || error "(1) Fail to stop mds2"
23667
23668         do_facet mgs $LCTL barrier_freeze $FSNAME 30
23669
23670         local b_status=$(barrier_stat)
23671         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
23672                 do_facet mgs $LCTL barrier_thaw $FSNAME
23673                 error "(2) unexpected barrier status $b_status"
23674         }
23675
23676         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23677                 error "(3) Fail to rescan barrier bitmap"
23678
23679         # Do not reduce barrier time - See LU-11873
23680         do_facet mgs $LCTL barrier_freeze $FSNAME 20
23681
23682         b_status=$(barrier_stat)
23683         [ "$b_status" = "'frozen'" ] ||
23684                 error "(4) unexpected barrier status $b_status"
23685
23686         do_facet mgs $LCTL barrier_thaw $FSNAME
23687         b_status=$(barrier_stat)
23688         [ "$b_status" = "'thawed'" ] ||
23689                 error "(5) unexpected barrier status $b_status"
23690
23691         local devname=$(mdsdevname 2)
23692
23693         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
23694
23695         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23696                 error "(7) Fail to rescan barrier bitmap"
23697
23698         post_801
23699 }
23700 run_test 801c "rescan barrier bitmap"
23701
23702 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
23703 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
23704 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
23705 saved_MOUNT_OPTS=$MOUNT_OPTS
23706
23707 cleanup_802a() {
23708         trap 0
23709
23710         stopall
23711         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
23712         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
23713         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
23714         MOUNT_OPTS=$saved_MOUNT_OPTS
23715         setupall
23716 }
23717
23718 test_802a() {
23719         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
23720         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23721         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23722                 skip "Need server version at least 2.9.55"
23723
23724         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
23725
23726         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23727
23728         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23729                 error "(2) Fail to copy"
23730
23731         trap cleanup_802a EXIT
23732
23733         # sync by force before remount as readonly
23734         sync; sync_all_data; sleep 3; sync_all_data
23735
23736         stopall
23737
23738         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
23739         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
23740         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
23741
23742         echo "Mount the server as read only"
23743         setupall server_only || error "(3) Fail to start servers"
23744
23745         echo "Mount client without ro should fail"
23746         mount_client $MOUNT &&
23747                 error "(4) Mount client without 'ro' should fail"
23748
23749         echo "Mount client with ro should succeed"
23750         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
23751         mount_client $MOUNT ||
23752                 error "(5) Mount client with 'ro' should succeed"
23753
23754         echo "Modify should be refused"
23755         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23756
23757         echo "Read should be allowed"
23758         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23759                 error "(7) Read should succeed under ro mode"
23760
23761         cleanup_802a
23762 }
23763 run_test 802a "simulate readonly device"
23764
23765 test_802b() {
23766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23767         remote_mds_nodsh && skip "remote MDS with nodsh"
23768
23769         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
23770                 skip "readonly option not available"
23771
23772         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
23773
23774         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23775                 error "(2) Fail to copy"
23776
23777         # write back all cached data before setting MDT to readonly
23778         cancel_lru_locks
23779         sync_all_data
23780
23781         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
23782         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
23783
23784         echo "Modify should be refused"
23785         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23786
23787         echo "Read should be allowed"
23788         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23789                 error "(7) Read should succeed under ro mode"
23790
23791         # disable readonly
23792         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
23793 }
23794 run_test 802b "be able to set MDTs to readonly"
23795
23796 test_803() {
23797         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23798         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23799                 skip "MDS needs to be newer than 2.10.54"
23800
23801         mkdir -p $DIR/$tdir
23802         # Create some objects on all MDTs to trigger related logs objects
23803         for idx in $(seq $MDSCOUNT); do
23804                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
23805                         $DIR/$tdir/dir${idx} ||
23806                         error "Fail to create $DIR/$tdir/dir${idx}"
23807         done
23808
23809         sync; sleep 3
23810         wait_delete_completed # ensure old test cleanups are finished
23811         echo "before create:"
23812         $LFS df -i $MOUNT
23813         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23814
23815         for i in {1..10}; do
23816                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
23817                         error "Fail to create $DIR/$tdir/foo$i"
23818         done
23819
23820         sync; sleep 3
23821         echo "after create:"
23822         $LFS df -i $MOUNT
23823         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23824
23825         # allow for an llog to be cleaned up during the test
23826         [ $after_used -ge $((before_used + 10 - 1)) ] ||
23827                 error "before ($before_used) + 10 > after ($after_used)"
23828
23829         for i in {1..10}; do
23830                 rm -rf $DIR/$tdir/foo$i ||
23831                         error "Fail to remove $DIR/$tdir/foo$i"
23832         done
23833
23834         sleep 3 # avoid MDT return cached statfs
23835         wait_delete_completed
23836         echo "after unlink:"
23837         $LFS df -i $MOUNT
23838         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23839
23840         # allow for an llog to be created during the test
23841         [ $after_used -le $((before_used + 1)) ] ||
23842                 error "after ($after_used) > before ($before_used) + 1"
23843 }
23844 run_test 803 "verify agent object for remote object"
23845
23846 test_804() {
23847         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23848         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23849                 skip "MDS needs to be newer than 2.10.54"
23850         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
23851
23852         mkdir -p $DIR/$tdir
23853         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
23854                 error "Fail to create $DIR/$tdir/dir0"
23855
23856         local fid=$($LFS path2fid $DIR/$tdir/dir0)
23857         local dev=$(mdsdevname 2)
23858
23859         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23860                 grep ${fid} || error "NOT found agent entry for dir0"
23861
23862         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
23863                 error "Fail to create $DIR/$tdir/dir1"
23864
23865         touch $DIR/$tdir/dir1/foo0 ||
23866                 error "Fail to create $DIR/$tdir/dir1/foo0"
23867         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
23868         local rc=0
23869
23870         for idx in $(seq $MDSCOUNT); do
23871                 dev=$(mdsdevname $idx)
23872                 do_facet mds${idx} \
23873                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23874                         grep ${fid} && rc=$idx
23875         done
23876
23877         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
23878                 error "Fail to rename foo0 to foo1"
23879         if [ $rc -eq 0 ]; then
23880                 for idx in $(seq $MDSCOUNT); do
23881                         dev=$(mdsdevname $idx)
23882                         do_facet mds${idx} \
23883                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23884                         grep ${fid} && rc=$idx
23885                 done
23886         fi
23887
23888         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
23889                 error "Fail to rename foo1 to foo2"
23890         if [ $rc -eq 0 ]; then
23891                 for idx in $(seq $MDSCOUNT); do
23892                         dev=$(mdsdevname $idx)
23893                         do_facet mds${idx} \
23894                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23895                         grep ${fid} && rc=$idx
23896                 done
23897         fi
23898
23899         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
23900
23901         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
23902                 error "Fail to link to $DIR/$tdir/dir1/foo2"
23903         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
23904                 error "Fail to rename foo2 to foo0"
23905         unlink $DIR/$tdir/dir1/foo0 ||
23906                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
23907         rm -rf $DIR/$tdir/dir0 ||
23908                 error "Fail to rm $DIR/$tdir/dir0"
23909
23910         for idx in $(seq $MDSCOUNT); do
23911                 dev=$(mdsdevname $idx)
23912                 rc=0
23913
23914                 stop mds${idx}
23915                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
23916                         rc=$?
23917                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
23918                         error "mount mds$idx failed"
23919                 df $MOUNT > /dev/null 2>&1
23920
23921                 # e2fsck should not return error
23922                 [ $rc -eq 0 ] ||
23923                         error "e2fsck detected error on MDT${idx}: rc=$rc"
23924         done
23925 }
23926 run_test 804 "verify agent entry for remote entry"
23927
23928 cleanup_805() {
23929         do_facet $SINGLEMDS zfs set quota=$old $fsset
23930         unlinkmany $DIR/$tdir/f- 1000000
23931         trap 0
23932 }
23933
23934 test_805() {
23935         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
23936         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
23937         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
23938                 skip "netfree not implemented before 0.7"
23939         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
23940                 skip "Need MDS version at least 2.10.57"
23941
23942         local fsset
23943         local freekb
23944         local usedkb
23945         local old
23946         local quota
23947         local pref="osd-zfs.$FSNAME-MDT0000."
23948
23949         # limit available space on MDS dataset to meet nospace issue
23950         # quickly. then ZFS 0.7.2 can use reserved space if asked
23951         # properly (using netfree flag in osd_declare_destroy()
23952         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
23953         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
23954                 gawk '{print $3}')
23955         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
23956         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
23957         let "usedkb=usedkb-freekb"
23958         let "freekb=freekb/2"
23959         if let "freekb > 5000"; then
23960                 let "freekb=5000"
23961         fi
23962         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
23963         trap cleanup_805 EXIT
23964         mkdir $DIR/$tdir
23965         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
23966                 error "Can't set PFL layout"
23967         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
23968         rm -rf $DIR/$tdir || error "not able to remove"
23969         do_facet $SINGLEMDS zfs set quota=$old $fsset
23970         trap 0
23971 }
23972 run_test 805 "ZFS can remove from full fs"
23973
23974 # Size-on-MDS test
23975 check_lsom_data()
23976 {
23977         local file=$1
23978         local size=$($LFS getsom -s $file)
23979         local expect=$(stat -c %s $file)
23980
23981         [[ $size == $expect ]] ||
23982                 error "$file expected size: $expect, got: $size"
23983
23984         local blocks=$($LFS getsom -b $file)
23985         expect=$(stat -c %b $file)
23986         [[ $blocks == $expect ]] ||
23987                 error "$file expected blocks: $expect, got: $blocks"
23988 }
23989
23990 check_lsom_size()
23991 {
23992         local size=$($LFS getsom -s $1)
23993         local expect=$2
23994
23995         [[ $size == $expect ]] ||
23996                 error "$file expected size: $expect, got: $size"
23997 }
23998
23999 test_806() {
24000         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24001                 skip "Need MDS version at least 2.11.52"
24002
24003         local bs=1048576
24004
24005         touch $DIR/$tfile || error "touch $tfile failed"
24006
24007         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24008         save_lustre_params client "llite.*.xattr_cache" > $save
24009         lctl set_param llite.*.xattr_cache=0
24010         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24011
24012         # single-threaded write
24013         echo "Test SOM for single-threaded write"
24014         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
24015                 error "write $tfile failed"
24016         check_lsom_size $DIR/$tfile $bs
24017
24018         local num=32
24019         local size=$(($num * $bs))
24020         local offset=0
24021         local i
24022
24023         echo "Test SOM for single client multi-threaded($num) write"
24024         $TRUNCATE $DIR/$tfile 0
24025         for ((i = 0; i < $num; i++)); do
24026                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24027                 local pids[$i]=$!
24028                 offset=$((offset + $bs))
24029         done
24030         for (( i=0; i < $num; i++ )); do
24031                 wait ${pids[$i]}
24032         done
24033         check_lsom_size $DIR/$tfile $size
24034
24035         $TRUNCATE $DIR/$tfile 0
24036         for ((i = 0; i < $num; i++)); do
24037                 offset=$((offset - $bs))
24038                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24039                 local pids[$i]=$!
24040         done
24041         for (( i=0; i < $num; i++ )); do
24042                 wait ${pids[$i]}
24043         done
24044         check_lsom_size $DIR/$tfile $size
24045
24046         # multi-client writes
24047         num=$(get_node_count ${CLIENTS//,/ })
24048         size=$(($num * $bs))
24049         offset=0
24050         i=0
24051
24052         echo "Test SOM for multi-client ($num) writes"
24053         $TRUNCATE $DIR/$tfile 0
24054         for client in ${CLIENTS//,/ }; do
24055                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24056                 local pids[$i]=$!
24057                 i=$((i + 1))
24058                 offset=$((offset + $bs))
24059         done
24060         for (( i=0; i < $num; i++ )); do
24061                 wait ${pids[$i]}
24062         done
24063         check_lsom_size $DIR/$tfile $offset
24064
24065         i=0
24066         $TRUNCATE $DIR/$tfile 0
24067         for client in ${CLIENTS//,/ }; do
24068                 offset=$((offset - $bs))
24069                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24070                 local pids[$i]=$!
24071                 i=$((i + 1))
24072         done
24073         for (( i=0; i < $num; i++ )); do
24074                 wait ${pids[$i]}
24075         done
24076         check_lsom_size $DIR/$tfile $size
24077
24078         # verify truncate
24079         echo "Test SOM for truncate"
24080         $TRUNCATE $DIR/$tfile 1048576
24081         check_lsom_size $DIR/$tfile 1048576
24082         $TRUNCATE $DIR/$tfile 1234
24083         check_lsom_size $DIR/$tfile 1234
24084
24085         # verify SOM blocks count
24086         echo "Verify SOM block count"
24087         $TRUNCATE $DIR/$tfile 0
24088         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
24089                 error "failed to write file $tfile"
24090         check_lsom_data $DIR/$tfile
24091 }
24092 run_test 806 "Verify Lazy Size on MDS"
24093
24094 test_807() {
24095         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24096         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24097                 skip "Need MDS version at least 2.11.52"
24098
24099         # Registration step
24100         changelog_register || error "changelog_register failed"
24101         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
24102         changelog_users $SINGLEMDS | grep -q $cl_user ||
24103                 error "User $cl_user not found in changelog_users"
24104
24105         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24106         save_lustre_params client "llite.*.xattr_cache" > $save
24107         lctl set_param llite.*.xattr_cache=0
24108         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24109
24110         rm -rf $DIR/$tdir || error "rm $tdir failed"
24111         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
24112         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
24113         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
24114         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
24115                 error "truncate $tdir/trunc failed"
24116
24117         local bs=1048576
24118         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
24119                 error "write $tfile failed"
24120
24121         # multi-client wirtes
24122         local num=$(get_node_count ${CLIENTS//,/ })
24123         local offset=0
24124         local i=0
24125
24126         echo "Test SOM for multi-client ($num) writes"
24127         touch $DIR/$tfile || error "touch $tfile failed"
24128         $TRUNCATE $DIR/$tfile 0
24129         for client in ${CLIENTS//,/ }; do
24130                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24131                 local pids[$i]=$!
24132                 i=$((i + 1))
24133                 offset=$((offset + $bs))
24134         done
24135         for (( i=0; i < $num; i++ )); do
24136                 wait ${pids[$i]}
24137         done
24138
24139         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
24140         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
24141         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
24142         check_lsom_data $DIR/$tdir/trunc
24143         check_lsom_data $DIR/$tdir/single_dd
24144         check_lsom_data $DIR/$tfile
24145
24146         rm -rf $DIR/$tdir
24147         # Deregistration step
24148         changelog_deregister || error "changelog_deregister failed"
24149 }
24150 run_test 807 "verify LSOM syncing tool"
24151
24152 check_som_nologged()
24153 {
24154         local lines=$($LFS changelog $FSNAME-MDT0000 |
24155                 grep 'x=trusted.som' | wc -l)
24156         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
24157 }
24158
24159 test_808() {
24160         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24161                 skip "Need MDS version at least 2.11.55"
24162
24163         # Registration step
24164         changelog_register || error "changelog_register failed"
24165
24166         touch $DIR/$tfile || error "touch $tfile failed"
24167         check_som_nologged
24168
24169         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
24170                 error "write $tfile failed"
24171         check_som_nologged
24172
24173         $TRUNCATE $DIR/$tfile 1234
24174         check_som_nologged
24175
24176         $TRUNCATE $DIR/$tfile 1048576
24177         check_som_nologged
24178
24179         # Deregistration step
24180         changelog_deregister || error "changelog_deregister failed"
24181 }
24182 run_test 808 "Check trusted.som xattr not logged in Changelogs"
24183
24184 check_som_nodata()
24185 {
24186         $LFS getsom $1
24187         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
24188 }
24189
24190 test_809() {
24191         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
24192                 skip "Need MDS version at least 2.11.56"
24193
24194         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
24195                 error "failed to create DoM-only file $DIR/$tfile"
24196         touch $DIR/$tfile || error "touch $tfile failed"
24197         check_som_nodata $DIR/$tfile
24198
24199         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
24200                 error "write $tfile failed"
24201         check_som_nodata $DIR/$tfile
24202
24203         $TRUNCATE $DIR/$tfile 1234
24204         check_som_nodata $DIR/$tfile
24205
24206         $TRUNCATE $DIR/$tfile 4097
24207         check_som_nodata $DIR/$file
24208 }
24209 run_test 809 "Verify no SOM xattr store for DoM-only files"
24210
24211 test_810() {
24212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24213         $GSS && skip_env "could not run with gss"
24214         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
24215                 skip "OST < 2.12.58 doesn't align checksum"
24216
24217         set_checksums 1
24218         stack_trap "set_checksums $ORIG_CSUM" EXIT
24219         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
24220
24221         local csum
24222         local before
24223         local after
24224         for csum in $CKSUM_TYPES; do
24225                 #define OBD_FAIL_OSC_NO_GRANT   0x411
24226                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
24227                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
24228                         eval set -- $i
24229                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
24230                         before=$(md5sum $DIR/$tfile)
24231                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
24232                         after=$(md5sum $DIR/$tfile)
24233                         [ "$before" == "$after" ] ||
24234                                 error "$csum: $before != $after bs=$1 seek=$2"
24235                 done
24236         done
24237 }
24238 run_test 810 "partial page writes on ZFS (LU-11663)"
24239
24240 test_812a() {
24241         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24242                 skip "OST < 2.12.51 doesn't support this fail_loc"
24243         [ "$SHARED_KEY" = true ] &&
24244                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24245
24246         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24247         # ensure ost1 is connected
24248         stat $DIR/$tfile >/dev/null || error "can't stat"
24249         wait_osc_import_state client ost1 FULL
24250         # no locks, no reqs to let the connection idle
24251         cancel_lru_locks osc
24252
24253         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24254 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24255         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24256         wait_osc_import_state client ost1 CONNECTING
24257         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24258
24259         stat $DIR/$tfile >/dev/null || error "can't stat file"
24260 }
24261 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
24262
24263 test_812b() { # LU-12378
24264         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24265                 skip "OST < 2.12.51 doesn't support this fail_loc"
24266         [ "$SHARED_KEY" = true ] &&
24267                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24268
24269         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
24270         # ensure ost1 is connected
24271         stat $DIR/$tfile >/dev/null || error "can't stat"
24272         wait_osc_import_state client ost1 FULL
24273         # no locks, no reqs to let the connection idle
24274         cancel_lru_locks osc
24275
24276         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24277 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24278         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24279         wait_osc_import_state client ost1 CONNECTING
24280         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24281
24282         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
24283         wait_osc_import_state client ost1 IDLE
24284 }
24285 run_test 812b "do not drop no resend request for idle connect"
24286
24287 test_813() {
24288         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
24289         [ -z "$file_heat_sav" ] && skip "no file heat support"
24290
24291         local readsample
24292         local writesample
24293         local readbyte
24294         local writebyte
24295         local readsample1
24296         local writesample1
24297         local readbyte1
24298         local writebyte1
24299
24300         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
24301         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
24302
24303         $LCTL set_param -n llite.*.file_heat=1
24304         echo "Turn on file heat"
24305         echo "Period second: $period_second, Decay percentage: $decay_pct"
24306
24307         echo "QQQQ" > $DIR/$tfile
24308         echo "QQQQ" > $DIR/$tfile
24309         echo "QQQQ" > $DIR/$tfile
24310         cat $DIR/$tfile > /dev/null
24311         cat $DIR/$tfile > /dev/null
24312         cat $DIR/$tfile > /dev/null
24313         cat $DIR/$tfile > /dev/null
24314
24315         local out=$($LFS heat_get $DIR/$tfile)
24316
24317         $LFS heat_get $DIR/$tfile
24318         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24319         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24320         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24321         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24322
24323         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
24324         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
24325         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
24326         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
24327
24328         sleep $((period_second + 3))
24329         echo "Sleep $((period_second + 3)) seconds..."
24330         # The recursion formula to calculate the heat of the file f is as
24331         # follow:
24332         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
24333         # Where Hi is the heat value in the period between time points i*I and
24334         # (i+1)*I; Ci is the access count in the period; the symbol P refers
24335         # to the weight of Ci.
24336         out=$($LFS heat_get $DIR/$tfile)
24337         $LFS heat_get $DIR/$tfile
24338         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24339         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24340         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24341         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24342
24343         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
24344                 error "read sample ($readsample) is wrong"
24345         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
24346                 error "write sample ($writesample) is wrong"
24347         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
24348                 error "read bytes ($readbyte) is wrong"
24349         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
24350                 error "write bytes ($writebyte) is wrong"
24351
24352         echo "QQQQ" > $DIR/$tfile
24353         echo "QQQQ" > $DIR/$tfile
24354         echo "QQQQ" > $DIR/$tfile
24355         cat $DIR/$tfile > /dev/null
24356         cat $DIR/$tfile > /dev/null
24357         cat $DIR/$tfile > /dev/null
24358         cat $DIR/$tfile > /dev/null
24359
24360         sleep $((period_second + 3))
24361         echo "Sleep $((period_second + 3)) seconds..."
24362
24363         out=$($LFS heat_get $DIR/$tfile)
24364         $LFS heat_get $DIR/$tfile
24365         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24366         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24367         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24368         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24369
24370         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
24371                 4 * $decay_pct) / 100") -eq 1 ] ||
24372                 error "read sample ($readsample1) is wrong"
24373         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
24374                 3 * $decay_pct) / 100") -eq 1 ] ||
24375                 error "write sample ($writesample1) is wrong"
24376         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
24377                 20 * $decay_pct) / 100") -eq 1 ] ||
24378                 error "read bytes ($readbyte1) is wrong"
24379         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
24380                 15 * $decay_pct) / 100") -eq 1 ] ||
24381                 error "write bytes ($writebyte1) is wrong"
24382
24383         echo "Turn off file heat for the file $DIR/$tfile"
24384         $LFS heat_set -o $DIR/$tfile
24385
24386         echo "QQQQ" > $DIR/$tfile
24387         echo "QQQQ" > $DIR/$tfile
24388         echo "QQQQ" > $DIR/$tfile
24389         cat $DIR/$tfile > /dev/null
24390         cat $DIR/$tfile > /dev/null
24391         cat $DIR/$tfile > /dev/null
24392         cat $DIR/$tfile > /dev/null
24393
24394         out=$($LFS heat_get $DIR/$tfile)
24395         $LFS heat_get $DIR/$tfile
24396         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24397         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24398         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24399         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24400
24401         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24402         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24403         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24404         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24405
24406         echo "Trun on file heat for the file $DIR/$tfile"
24407         $LFS heat_set -O $DIR/$tfile
24408
24409         echo "QQQQ" > $DIR/$tfile
24410         echo "QQQQ" > $DIR/$tfile
24411         echo "QQQQ" > $DIR/$tfile
24412         cat $DIR/$tfile > /dev/null
24413         cat $DIR/$tfile > /dev/null
24414         cat $DIR/$tfile > /dev/null
24415         cat $DIR/$tfile > /dev/null
24416
24417         out=$($LFS heat_get $DIR/$tfile)
24418         $LFS heat_get $DIR/$tfile
24419         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24420         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24421         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24422         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24423
24424         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
24425         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
24426         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
24427         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
24428
24429         $LFS heat_set -c $DIR/$tfile
24430         $LCTL set_param -n llite.*.file_heat=0
24431         echo "Turn off file heat support for the Lustre filesystem"
24432
24433         echo "QQQQ" > $DIR/$tfile
24434         echo "QQQQ" > $DIR/$tfile
24435         echo "QQQQ" > $DIR/$tfile
24436         cat $DIR/$tfile > /dev/null
24437         cat $DIR/$tfile > /dev/null
24438         cat $DIR/$tfile > /dev/null
24439         cat $DIR/$tfile > /dev/null
24440
24441         out=$($LFS heat_get $DIR/$tfile)
24442         $LFS heat_get $DIR/$tfile
24443         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24444         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24445         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24446         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24447
24448         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24449         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24450         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24451         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24452
24453         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
24454         rm -f $DIR/$tfile
24455 }
24456 run_test 813 "File heat verfication"
24457
24458 test_814()
24459 {
24460         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
24461         echo -n y >> $DIR/$tfile
24462         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
24463         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
24464 }
24465 run_test 814 "sparse cp works as expected (LU-12361)"
24466
24467 test_815()
24468 {
24469         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
24470         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
24471 }
24472 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
24473
24474 test_816() {
24475         [ "$SHARED_KEY" = true ] &&
24476                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24477
24478         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24479         # ensure ost1 is connected
24480         stat $DIR/$tfile >/dev/null || error "can't stat"
24481         wait_osc_import_state client ost1 FULL
24482         # no locks, no reqs to let the connection idle
24483         cancel_lru_locks osc
24484         lru_resize_disable osc
24485         local before
24486         local now
24487         before=$($LCTL get_param -n \
24488                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24489
24490         wait_osc_import_state client ost1 IDLE
24491         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
24492         now=$($LCTL get_param -n \
24493               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24494         [ $before == $now ] || error "lru_size changed $before != $now"
24495 }
24496 run_test 816 "do not reset lru_resize on idle reconnect"
24497
24498 cleanup_817() {
24499         umount $tmpdir
24500         exportfs -u localhost:$DIR/nfsexp
24501         rm -rf $DIR/nfsexp
24502 }
24503
24504 test_817() {
24505         systemctl restart nfs-server.service || skip "failed to restart nfsd"
24506
24507         mkdir -p $DIR/nfsexp
24508         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
24509                 error "failed to export nfs"
24510
24511         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
24512         stack_trap cleanup_817 EXIT
24513
24514         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
24515                 error "failed to mount nfs to $tmpdir"
24516
24517         cp /bin/true $tmpdir
24518         $DIR/nfsexp/true || error "failed to execute 'true' command"
24519 }
24520 run_test 817 "nfsd won't cache write lock for exec file"
24521
24522 test_818() {
24523         mkdir $DIR/$tdir
24524         $LFS setstripe -c1 -i0 $DIR/$tfile
24525         $LFS setstripe -c1 -i1 $DIR/$tfile
24526         stop $SINGLEMDS
24527         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
24528         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
24529         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
24530                 error "start $SINGLEMDS failed"
24531         rm -rf $DIR/$tdir
24532 }
24533 run_test 818 "unlink with failed llog"
24534
24535 test_819a() {
24536         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24537         cancel_lru_locks osc
24538         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24539         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24540         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
24541         rm -f $TDIR/$tfile
24542 }
24543 run_test 819a "too big niobuf in read"
24544
24545 test_819b() {
24546         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24547         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24548         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24549         cancel_lru_locks osc
24550         sleep 1
24551         rm -f $TDIR/$tfile
24552 }
24553 run_test 819b "too big niobuf in write"
24554
24555
24556 function test_820_start_ost() {
24557         sleep 5
24558
24559         for num in $(seq $OSTCOUNT); do
24560                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
24561         done
24562 }
24563
24564 test_820() {
24565         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24566
24567         mkdir $DIR/$tdir
24568         umount_client $MOUNT || error "umount failed"
24569         for num in $(seq $OSTCOUNT); do
24570                 stop ost$num
24571         done
24572
24573         # mount client with no active OSTs
24574         # so that the client can't initialize max LOV EA size
24575         # from OSC notifications
24576         mount_client $MOUNT || error "mount failed"
24577         # delay OST starting to keep this 0 max EA size for a while
24578         test_820_start_ost &
24579
24580         # create a directory on MDS2
24581         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
24582                 error "Failed to create directory"
24583         # open intent should update default EA size
24584         # see mdc_update_max_ea_from_body()
24585         # notice this is the very first RPC to MDS2
24586         cp /etc/services $DIR/$tdir/mds2 ||
24587                 error "Failed to copy files to mds$n"
24588 }
24589 run_test 820 "update max EA from open intent"
24590
24591 #
24592 # tests that do cleanup/setup should be run at the end
24593 #
24594
24595 test_900() {
24596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24597         local ls
24598
24599         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
24600         $LCTL set_param fail_loc=0x903
24601
24602         cancel_lru_locks MGC
24603
24604         FAIL_ON_ERROR=true cleanup
24605         FAIL_ON_ERROR=true setup
24606 }
24607 run_test 900 "umount should not race with any mgc requeue thread"
24608
24609 # LUS-6253/LU-11185
24610 test_901() {
24611         local oldc
24612         local newc
24613         local olds
24614         local news
24615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24616
24617         # some get_param have a bug to handle dot in param name
24618         cancel_lru_locks MGC
24619         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24620         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24621         umount_client $MOUNT || error "umount failed"
24622         mount_client $MOUNT || error "mount failed"
24623         cancel_lru_locks MGC
24624         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24625         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24626
24627         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
24628         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
24629
24630         return 0
24631 }
24632 run_test 901 "don't leak a mgc lock on client umount"
24633
24634 # LU-13377
24635 test_902() {
24636         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
24637                 skip "client does not have LU-13377 fix"
24638         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
24639         $LCTL set_param fail_loc=0x1415
24640         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24641         cancel_lru_locks osc
24642         rm -f $DIR/$tfile
24643 }
24644 run_test 902 "test short write doesn't hang lustre"
24645
24646 complete $SECONDS
24647 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
24648 check_and_cleanup_lustre
24649 if [ "$I_MOUNTED" != "yes" ]; then
24650         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
24651 fi
24652 exit_status